diff --git a/Makefile b/Makefile
index b243d267966835ad687b03b6b8d34275e7c42660..03e3bf4c6f93789301be3058765e8189cccea45e 100644
--- a/Makefile
+++ b/Makefile
@@ -10,11 +10,6 @@ geth:
 	@echo "Done building."
 	@echo "Run \"$(GOBIN)/geth\" to launch geth."
 
-console:
-	build/env.sh go install -v $(shell build/ldflags.sh) ./cmd/console
-	@echo "Done building."
-	@echo "Run \"$(GOBIN)/console\" to launch the console."
-
 mist:
 	build/env.sh go install -v $(shell build/ldflags.sh) ./cmd/mist
 	@echo "Done building."
diff --git a/cmd/console/admin.go b/cmd/console/admin.go
deleted file mode 100644
index dee88e3a0adf18d11e79ec993e83f264ee4a7542..0000000000000000000000000000000000000000
--- a/cmd/console/admin.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package main
-
-/*
-node admin bindings
-*/
-
-func (js *jsre) adminBindings() {
-
-}
diff --git a/cmd/console/contracts.go b/cmd/console/contracts.go
deleted file mode 100644
index 1f27838d15f7ac6fe8edc06758e8e7cd13ed2c6d..0000000000000000000000000000000000000000
--- a/cmd/console/contracts.go
+++ /dev/null
@@ -1,6 +0,0 @@
-package main
-
-var (
-	globalRegistrar     = `var GlobalRegistrar = web3.eth.contract([{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"o_subRegistrar","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"Registrar","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setAddress","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"disown","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"address"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"}]);`
-	globalRegistrarAddr = "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
-)
diff --git a/cmd/console/js.go b/cmd/console/js.go
deleted file mode 100644
index 15ea9bedd864bcf783d00476027abef388335d38..0000000000000000000000000000000000000000
--- a/cmd/console/js.go
+++ /dev/null
@@ -1,454 +0,0 @@
-// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301  USA
-
-package main
-
-import (
-	"bufio"
-	"fmt"
-	"math/big"
-	"os"
-	"os/signal"
-	"path/filepath"
-	"strings"
-
-	"encoding/json"
-
-	"sort"
-
-	"github.com/codegangsta/cli"
-	"github.com/ethereum/go-ethereum/cmd/utils"
-	"github.com/ethereum/go-ethereum/common/docserver"
-	re "github.com/ethereum/go-ethereum/jsre"
-	"github.com/ethereum/go-ethereum/rpc"
-	"github.com/ethereum/go-ethereum/rpc/api"
-	"github.com/ethereum/go-ethereum/rpc/codec"
-	"github.com/ethereum/go-ethereum/rpc/comms"
-	"github.com/ethereum/go-ethereum/rpc/shared"
-	"github.com/peterh/liner"
-	"github.com/robertkrimen/otto"
-)
-
-type prompter interface {
-	AppendHistory(string)
-	Prompt(p string) (string, error)
-	PasswordPrompt(p string) (string, error)
-}
-
-type dumbterm struct{ r *bufio.Reader }
-
-func (r dumbterm) Prompt(p string) (string, error) {
-	fmt.Print(p)
-	line, err := r.r.ReadString('\n')
-	return strings.TrimSuffix(line, "\n"), err
-}
-
-func (r dumbterm) PasswordPrompt(p string) (string, error) {
-	fmt.Println("!! Unsupported terminal, password will echo.")
-	fmt.Print(p)
-	input, err := bufio.NewReader(os.Stdin).ReadString('\n')
-	fmt.Println()
-	return input, err
-}
-
-func (r dumbterm) AppendHistory(string) {}
-
-type jsre struct {
-	re      *re.JSRE
-	wait    chan *big.Int
-	ps1     string
-	atexit  func()
-	datadir string
-	prompter
-}
-
-var (
-	loadedModulesMethods map[string][]string
-)
-
-func loadAutoCompletion(js *jsre, ipcpath string) {
-	modules, err := js.suportedApis(ipcpath)
-	if err != nil {
-		utils.Fatalf("Unable to determine supported modules - %v", err)
-	}
-
-	loadedModulesMethods = make(map[string][]string)
-	for module, _ := range modules {
-		loadedModulesMethods[module] = api.AutoCompletion[module]
-	}
-}
-
-func keywordCompleter(line string) []string {
-	results := make([]string, 0)
-
-	if strings.Contains(line, ".") {
-		elements := strings.Split(line, ".")
-		if len(elements) == 2 {
-			module := elements[0]
-			partialMethod := elements[1]
-			if methods, found := loadedModulesMethods[module]; found {
-				for _, method := range methods {
-					if strings.HasPrefix(method, partialMethod) { // e.g. debug.se
-						results = append(results, module+"."+method)
-					}
-				}
-			}
-		}
-	} else {
-		for module, methods := range loadedModulesMethods {
-			if line == module { // user typed in full module name, show all methods
-				for _, method := range methods {
-					results = append(results, module+"."+method)
-				}
-			} else if strings.HasPrefix(module, line) { // partial method name, e.g. admi
-				results = append(results, module)
-			}
-		}
-	}
-	return results
-}
-
-func apiWordCompleter(line string, pos int) (head string, completions []string, tail string) {
-	if len(line) == 0 {
-		return "", nil, ""
-	}
-
-	i := 0
-	for i = pos - 1; i > 0; i-- {
-		if line[i] == '.' || (line[i] >= 'a' && line[i] <= 'z') || (line[i] >= 'A' && line[i] <= 'Z') {
-			continue
-		}
-		if i >= 3 && line[i] == '3' && line[i-3] == 'w' && line[i-2] == 'e' && line[i-1] == 'b' {
-			continue
-		}
-		i += 1
-		break
-	}
-
-	begin := line[:i]
-	keyword := line[i:pos]
-	end := line[pos:]
-
-	completionWords := keywordCompleter(keyword)
-	return begin, completionWords, end
-}
-
-func newJSRE(libPath, ipcpath string) *jsre {
-	js := &jsre{ps1: "> "}
-	js.wait = make(chan *big.Int)
-
-	// update state in separare forever blocks
-	js.re = re.New(libPath)
-	js.apiBindings(ipcpath)
-
-	if !liner.TerminalSupported() {
-		js.prompter = dumbterm{bufio.NewReader(os.Stdin)}
-	} else {
-		lr := liner.NewLiner()
-		js.withHistory(func(hist *os.File) { lr.ReadHistory(hist) })
-		lr.SetCtrlCAborts(true)
-		loadAutoCompletion(js, ipcpath)
-		lr.SetWordCompleter(apiWordCompleter)
-		lr.SetTabCompletionStyle(liner.TabPrints)
-		js.prompter = lr
-		js.atexit = func() {
-			js.withHistory(func(hist *os.File) { hist.Truncate(0); lr.WriteHistory(hist) })
-			lr.Close()
-			close(js.wait)
-		}
-	}
-	return js
-}
-
-func (js *jsre) apiBindings(ipcpath string) {
-	ethApi := rpc.NewEthereumApi(nil)
-	jeth := rpc.NewJeth(ethApi, js.re, ipcpath)
-
-	js.re.Set("jeth", struct{}{})
-	t, _ := js.re.Get("jeth")
-	jethObj := t.Object()
-	jethObj.Set("send", jeth.SendIpc)
-	jethObj.Set("sendAsync", jeth.SendIpc)
-
-	err := js.re.Compile("bignumber.js", re.BigNumber_JS)
-	if err != nil {
-		utils.Fatalf("Error loading bignumber.js: %v", err)
-	}
-
-	err = js.re.Compile("ethereum.js", re.Web3_JS)
-	if err != nil {
-		utils.Fatalf("Error loading web3.js: %v", err)
-	}
-
-	_, err = js.re.Eval("var web3 = require('web3');")
-	if err != nil {
-		utils.Fatalf("Error requiring web3: %v", err)
-	}
-
-	_, err = js.re.Eval("web3.setProvider(jeth)")
-	if err != nil {
-		utils.Fatalf("Error setting web3 provider: %v", err)
-	}
-
-	apis, err := js.suportedApis(ipcpath)
-	if err != nil {
-		utils.Fatalf("Unable to determine supported api's: %v", err)
-	}
-
-	// load only supported API's in javascript runtime
-	shortcuts := "var eth = web3.eth; "
-	for apiName, _ := range apis {
-		if apiName == api.Web3ApiName || apiName == api.EthApiName {
-			continue // manually mapped
-		}
-
-		if err = js.re.Compile(fmt.Sprintf("%s.js", apiName), api.Javascript(apiName)); err == nil {
-			shortcuts += fmt.Sprintf("var %s = web3.%s; ", apiName, apiName)
-		} else {
-			utils.Fatalf("Error loading %s.js: %v", apiName, err)
-		}
-	}
-
-	_, err = js.re.Eval(shortcuts)
-
-	if err != nil {
-		utils.Fatalf("Error setting namespaces: %v", err)
-	}
-
-	js.re.Eval(globalRegistrar + "registrar = GlobalRegistrar.at(\"" + globalRegistrarAddr + "\");")
-}
-
-var ds, _ = docserver.New("/")
-
-/*
-func (self *jsre) ConfirmTransaction(tx string) bool {
-	if self.ethereum.NatSpec {
-		notice := natspec.GetNotice(self.xeth, tx, ds)
-		fmt.Println(notice)
-		answer, _ := self.Prompt("Confirm Transaction [y/n]")
-		return strings.HasPrefix(strings.Trim(answer, " "), "y")
-	} else {
-		return true
-	}
-}
-
-func (self *jsre) UnlockAccount(addr []byte) bool {
-	fmt.Printf("Please unlock account %x.\n", addr)
-	pass, err := self.PasswordPrompt("Passphrase: ")
-	if err != nil {
-		return false
-	}
-	// TODO: allow retry
-	if err := self.ethereum.AccountManager().Unlock(common.BytesToAddress(addr), pass); err != nil {
-		return false
-	} else {
-		fmt.Println("Account is now unlocked for this session.")
-		return true
-	}
-}
-*/
-
-func (self *jsre) exec(filename string) error {
-	if err := self.re.Exec(filename); err != nil {
-		self.re.Stop(false)
-		return fmt.Errorf("Javascript Error: %v", err)
-	}
-	self.re.Stop(true)
-	return nil
-}
-
-func (self *jsre) suportedApis(ipcpath string) (map[string]string, error) {
-	config := comms.IpcConfig{
-		Endpoint: ipcpath,
-	}
-
-	client, err := comms.NewIpcClient(config, codec.JSON)
-	if err != nil {
-		return nil, err
-	}
-
-	req := shared.Request{
-		Id:      1,
-		Jsonrpc: "2.0",
-		Method:  "modules",
-	}
-
-	err = client.Send(req)
-	if err != nil {
-		return nil, err
-	}
-
-	res, err := client.Recv()
-	if err != nil {
-		return nil, err
-	}
-
-	if sucRes, ok := res.(shared.SuccessResponse); ok {
-		data, _ := json.Marshal(sucRes.Result)
-		apis := make(map[string]string)
-		err = json.Unmarshal(data, &apis)
-		if err == nil {
-			return apis, nil
-		}
-	}
-
-	return nil, fmt.Errorf("Unable to determine supported API's")
-}
-
-// show summary of current geth instance
-func (self *jsre) welcome(ipcpath string) {
-	self.re.Eval(`console.log('instance: ' + web3.version.client);`)
-	self.re.Eval(`console.log(' datadir: ' + admin.datadir);`)
-	self.re.Eval(`console.log("coinbase: " + eth.coinbase);`)
-	self.re.Eval(`var lastBlockTimestamp = 1000 * eth.getBlock(eth.blockNumber).timestamp`)
-	self.re.Eval(`console.log("at block: " + eth.blockNumber + " (" + new Date(lastBlockTimestamp).toLocaleDateString()
-		+ " " + new Date(lastBlockTimestamp).toLocaleTimeString() + ")");`)
-
-	if modules, err := self.suportedApis(ipcpath); err == nil {
-		loadedModules := make([]string, 0)
-		for api, version := range modules {
-			loadedModules = append(loadedModules, fmt.Sprintf("%s:%s", api, version))
-		}
-		sort.Strings(loadedModules)
-
-		self.re.Eval(fmt.Sprintf("var modules = '%s';", strings.Join(loadedModules, " ")))
-		self.re.Eval(`console.log(" modules: " + modules);`)
-	}
-}
-
-func (self *jsre) batch(args cli.Args) {
-	statement := strings.Join(args, " ")
-	val, err := self.re.Run(statement)
-
-	if err != nil {
-		fmt.Printf("error: %v", err)
-	} else if val.IsDefined() && val.IsObject() {
-		obj, _ := self.re.Get("ret_result")
-		fmt.Printf("%v", obj)
-	} else if val.IsDefined() {
-		fmt.Printf("%v", val)
-	}
-
-	if self.atexit != nil {
-		self.atexit()
-	}
-
-	self.re.Stop(false)
-}
-
-func (self *jsre) interactive(ipcpath string) {
-	self.welcome(ipcpath)
-
-	// Read input lines.
-	prompt := make(chan string)
-	inputln := make(chan string)
-	go func() {
-		defer close(inputln)
-		for {
-			line, err := self.Prompt(<-prompt)
-			if err != nil {
-				return
-			}
-			inputln <- line
-		}
-	}()
-	// Wait for Ctrl-C, too.
-	sig := make(chan os.Signal, 1)
-	signal.Notify(sig, os.Interrupt)
-
-	defer func() {
-		if self.atexit != nil {
-			self.atexit()
-		}
-		self.re.Stop(false)
-	}()
-	for {
-		prompt <- self.ps1
-		select {
-		case <-sig:
-			fmt.Println("caught interrupt, exiting")
-			return
-		case input, ok := <-inputln:
-			if !ok || indentCount <= 0 && input == "exit" {
-				return
-			}
-			if input == "" {
-				continue
-			}
-			str += input + "\n"
-			self.setIndent()
-			if indentCount <= 0 {
-				hist := str[:len(str)-1]
-				self.AppendHistory(hist)
-				self.parseInput(str)
-				str = ""
-			}
-		}
-	}
-}
-
-func (self *jsre) withHistory(op func(*os.File)) {
-	hist, err := os.OpenFile(filepath.Join(self.datadir, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
-	if err != nil {
-		fmt.Printf("unable to open history file: %v\n", err)
-		return
-	}
-	op(hist)
-	hist.Close()
-}
-
-func (self *jsre) parseInput(code string) {
-	defer func() {
-		if r := recover(); r != nil {
-			fmt.Println("[native] error", r)
-		}
-	}()
-	value, err := self.re.Run(code)
-	if err != nil {
-		if ottoErr, ok := err.(*otto.Error); ok {
-			fmt.Println(ottoErr.String())
-		} else {
-			fmt.Println(err)
-		}
-		return
-	}
-	self.printValue(value)
-}
-
-var indentCount = 0
-var str = ""
-
-func (self *jsre) setIndent() {
-	open := strings.Count(str, "{")
-	open += strings.Count(str, "(")
-	closed := strings.Count(str, "}")
-	closed += strings.Count(str, ")")
-	indentCount = open - closed
-	if indentCount <= 0 {
-		self.ps1 = "> "
-	} else {
-		self.ps1 = strings.Join(make([]string, indentCount*2), "..")
-		self.ps1 += " "
-	}
-}
-
-func (self *jsre) printValue(v interface{}) {
-	val, err := self.re.PrettyPrint(v)
-	if err == nil {
-		fmt.Printf("%v", val)
-	}
-}
diff --git a/cmd/console/main.go b/cmd/console/main.go
deleted file mode 100644
index 00a9ca9c4555c68b5f4353681d1f910355abd597..0000000000000000000000000000000000000000
--- a/cmd/console/main.go
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-	This file is part of go-ethereum
-
-	go-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	go-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with go-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * @authors
- * 	Jeffrey Wilcke <i@jev.io>
- */
-package main
-
-import (
-	"fmt"
-	"io"
-	"os"
-
-	"github.com/codegangsta/cli"
-	"github.com/ethereum/go-ethereum/cmd/utils"
-	"github.com/ethereum/go-ethereum/logger"
-	"github.com/mattn/go-colorable"
-	"github.com/mattn/go-isatty"
-)
-
-const (
-	ClientIdentifier = "Geth console"
-	Version          = "0.9.27"
-)
-
-var (
-	gitCommit       string // set via linker flag
-	nodeNameVersion string
-	app             = utils.NewApp(Version, "the geth console")
-)
-
-func init() {
-	if gitCommit == "" {
-		nodeNameVersion = Version
-	} else {
-		nodeNameVersion = Version + "-" + gitCommit[:8]
-	}
-
-	app.Action = run
-	app.Flags = []cli.Flag{
-		utils.IPCPathFlag,
-		utils.VerbosityFlag,
-		utils.JSpathFlag,
-	}
-
-	app.Before = func(ctx *cli.Context) error {
-		utils.SetupLogger(ctx)
-		return nil
-	}
-}
-
-func main() {
-	// Wrap the standard output with a colorified stream (windows)
-	if isatty.IsTerminal(os.Stdout.Fd()) {
-		if pr, pw, err := os.Pipe(); err == nil {
-			go io.Copy(colorable.NewColorableStdout(), pr)
-			os.Stdout = pw
-		}
-	}
-
-	var interrupted = false
-	utils.RegisterInterrupt(func(os.Signal) {
-		interrupted = true
-	})
-	utils.HandleInterrupt()
-
-	if err := app.Run(os.Args); err != nil {
-		fmt.Fprintln(os.Stderr, "Error: ", err)
-	}
-
-	// we need to run the interrupt callbacks in case gui is closed
-	// this skips if we got here by actual interrupt stopping the GUI
-	if !interrupted {
-		utils.RunInterruptCallbacks(os.Interrupt)
-	}
-	logger.Flush()
-}
-
-func run(ctx *cli.Context) {
-	jspath := ctx.GlobalString(utils.JSpathFlag.Name)
-	ipcpath := utils.IpcSocketPath(ctx)
-	repl := newJSRE(jspath, ipcpath)
-
-	if ctx.Args().Present() {
-		repl.batch(ctx.Args())
-	} else {
-		repl.interactive(ipcpath)
-	}
-}
diff --git a/cmd/geth/admin.go b/cmd/geth/admin.go
deleted file mode 100644
index 33ef6979294c9a5a83d6f36f34923082c9602abd..0000000000000000000000000000000000000000
--- a/cmd/geth/admin.go
+++ /dev/null
@@ -1,937 +0,0 @@
-package main
-
-import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	"math/big"
-	"strconv"
-	"time"
-
-	"github.com/ethereum/ethash"
-	"github.com/ethereum/go-ethereum/accounts"
-	"github.com/ethereum/go-ethereum/cmd/utils"
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/common/compiler"
-	"github.com/ethereum/go-ethereum/common/natspec"
-	"github.com/ethereum/go-ethereum/common/resolver"
-	"github.com/ethereum/go-ethereum/core/state"
-	"github.com/ethereum/go-ethereum/core/types"
-	"github.com/ethereum/go-ethereum/core/vm"
-	"github.com/ethereum/go-ethereum/crypto"
-	"github.com/ethereum/go-ethereum/logger/glog"
-	"github.com/ethereum/go-ethereum/rlp"
-	"github.com/ethereum/go-ethereum/rpc"
-	"github.com/ethereum/go-ethereum/xeth"
-	"github.com/robertkrimen/otto"
-	"gopkg.in/fatih/set.v0"
-)
-
-/*
-node admin bindings
-*/
-
-func (js *jsre) adminBindings() {
-	ethO, _ := js.re.Get("eth")
-	eth := ethO.Object()
-	eth.Set("pendingTransactions", js.pendingTransactions)
-	eth.Set("resend", js.resend)
-	eth.Set("sign", js.sign)
-
-	js.re.Set("admin", struct{}{})
-	t, _ := js.re.Get("admin")
-	admin := t.Object()
-	admin.Set("addPeer", js.addPeer)
-	admin.Set("startRPC", js.startRPC)
-	admin.Set("stopRPC", js.stopRPC)
-	admin.Set("nodeInfo", js.nodeInfo)
-	admin.Set("peers", js.peers)
-	admin.Set("newAccount", js.newAccount)
-	admin.Set("unlock", js.unlock)
-	admin.Set("import", js.importChain)
-	admin.Set("export", js.exportChain)
-	admin.Set("verbosity", js.verbosity)
-	admin.Set("progress", js.syncProgress)
-	admin.Set("setSolc", js.setSolc)
-
-	admin.Set("contractInfo", struct{}{})
-	t, _ = admin.Get("contractInfo")
-	cinfo := t.Object()
-	// newRegistry officially not documented temporary option
-	cinfo.Set("start", js.startNatSpec)
-	cinfo.Set("stop", js.stopNatSpec)
-	cinfo.Set("newRegistry", js.newRegistry)
-	cinfo.Set("get", js.getContractInfo)
-	cinfo.Set("register", js.register)
-	cinfo.Set("registerUrl", js.registerUrl)
-	// cinfo.Set("verify", js.verify)
-
-	admin.Set("miner", struct{}{})
-	t, _ = admin.Get("miner")
-	miner := t.Object()
-	miner.Set("start", js.startMining)
-	miner.Set("stop", js.stopMining)
-	miner.Set("hashrate", js.hashrate)
-	miner.Set("setExtra", js.setExtra)
-	miner.Set("setGasPrice", js.setGasPrice)
-	miner.Set("startAutoDAG", js.startAutoDAG)
-	miner.Set("stopAutoDAG", js.stopAutoDAG)
-	miner.Set("makeDAG", js.makeDAG)
-
-	admin.Set("txPool", struct{}{})
-	t, _ = admin.Get("txPool")
-	txPool := t.Object()
-	txPool.Set("pending", js.allPendingTransactions)
-	txPool.Set("queued", js.allQueuedTransactions)
-
-	admin.Set("debug", struct{}{})
-	t, _ = admin.Get("debug")
-	debug := t.Object()
-	js.re.Set("sleep", js.sleep)
-	debug.Set("backtrace", js.backtrace)
-	debug.Set("printBlock", js.printBlock)
-	debug.Set("dumpBlock", js.dumpBlock)
-	debug.Set("getBlockRlp", js.getBlockRlp)
-	debug.Set("setHead", js.setHead)
-	debug.Set("processBlock", js.debugBlock)
-	debug.Set("seedhash", js.seedHash)
-	debug.Set("insertBlock", js.insertBlockRlp)
-	// undocumented temporary
-	debug.Set("waitForBlocks", js.waitForBlocks)
-}
-
-// generic helper to getBlock by Number/Height or Hex depending on autodetected input
-// if argument is missing the current block is returned
-// if block is not found or there is problem with decoding
-// the appropriate value is returned and block is guaranteed to be nil
-func (js *jsre) getBlock(call otto.FunctionCall) (*types.Block, error) {
-	var block *types.Block
-	if len(call.ArgumentList) > 0 {
-		if call.Argument(0).IsNumber() {
-			num, _ := call.Argument(0).ToInteger()
-			block = js.ethereum.ChainManager().GetBlockByNumber(uint64(num))
-		} else if call.Argument(0).IsString() {
-			hash, _ := call.Argument(0).ToString()
-			block = js.ethereum.ChainManager().GetBlock(common.HexToHash(hash))
-		} else {
-			return nil, errors.New("invalid argument for dump. Either hex string or number")
-		}
-	} else {
-		block = js.ethereum.ChainManager().CurrentBlock()
-	}
-
-	if block == nil {
-		return nil, errors.New("block not found")
-	}
-	return block, nil
-}
-
-func (js *jsre) seedHash(call otto.FunctionCall) otto.Value {
-	if len(call.ArgumentList) > 0 {
-		if call.Argument(0).IsNumber() {
-			num, _ := call.Argument(0).ToInteger()
-			hash, err := ethash.GetSeedHash(uint64(num))
-			if err != nil {
-				fmt.Println(err)
-				return otto.UndefinedValue()
-			}
-			v, _ := call.Otto.ToValue(fmt.Sprintf("0x%x", hash))
-			return v
-		} else {
-			fmt.Println("arg not a number")
-		}
-	} else {
-		fmt.Println("requires number argument")
-	}
-
-	return otto.UndefinedValue()
-}
-
-func (js *jsre) allPendingTransactions(call otto.FunctionCall) otto.Value {
-	txs := js.ethereum.TxPool().GetTransactions()
-
-	ltxs := make([]*tx, len(txs))
-	for i, tx := range txs {
-		// no need to check err
-		ltxs[i] = newTx(tx)
-	}
-
-	v, _ := call.Otto.ToValue(ltxs)
-	return v
-}
-
-func (js *jsre) allQueuedTransactions(call otto.FunctionCall) otto.Value {
-	txs := js.ethereum.TxPool().GetQueuedTransactions()
-
-	ltxs := make([]*tx, len(txs))
-	for i, tx := range txs {
-		// no need to check err
-		ltxs[i] = newTx(tx)
-	}
-
-	v, _ := call.Otto.ToValue(ltxs)
-	return v
-}
-
-func (js *jsre) pendingTransactions(call otto.FunctionCall) otto.Value {
-	txs := js.ethereum.TxPool().GetTransactions()
-
-	// grab the accounts from the account manager. This will help with determening which
-	// transactions should be returned.
-	accounts, err := js.ethereum.AccountManager().Accounts()
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	// Add the accouns to a new set
-	accountSet := set.New()
-	for _, account := range accounts {
-		accountSet.Add(account.Address)
-	}
-
-	//ltxs := make([]*tx, len(txs))
-	var ltxs []*tx
-	for _, tx := range txs {
-		if from, _ := tx.From(); accountSet.Has(from) {
-			ltxs = append(ltxs, newTx(tx))
-		}
-	}
-
-	v, _ := call.Otto.ToValue(ltxs)
-	return v
-}
-
-func (js *jsre) resend(call otto.FunctionCall) otto.Value {
-	if len(call.ArgumentList) == 0 {
-		fmt.Println("first argument must be a transaction")
-		return otto.FalseValue()
-	}
-
-	v, err := call.Argument(0).Export()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	if tx, ok := v.(*tx); ok {
-		gl, gp := tx.GasLimit, tx.GasPrice
-		if len(call.ArgumentList) > 1 {
-			gp = call.Argument(1).String()
-		}
-		if len(call.ArgumentList) > 2 {
-			gl = call.Argument(2).String()
-		}
-
-		ret, err := js.xeth.Transact(tx.From, tx.To, tx.Nonce, tx.Value, gl, gp, tx.Data)
-		if err != nil {
-			fmt.Println(err)
-			return otto.FalseValue()
-		}
-		js.ethereum.TxPool().RemoveTransactions(types.Transactions{tx.tx})
-
-		v, _ := call.Otto.ToValue(ret)
-		return v
-	}
-
-	fmt.Println("first argument must be a transaction")
-	return otto.FalseValue()
-}
-
-func (js *jsre) sign(call otto.FunctionCall) otto.Value {
-	if len(call.ArgumentList) != 2 {
-		fmt.Println("requires 2 arguments: eth.sign(signer, data)")
-		return otto.UndefinedValue()
-	}
-	signer, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	data, err := call.Argument(1).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-	signed, err := js.xeth.Sign(signer, data, false)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-	v, _ := call.Otto.ToValue(signed)
-	return v
-}
-
-func (js *jsre) debugBlock(call otto.FunctionCall) otto.Value {
-	block, err := js.getBlock(call)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	tstart := time.Now()
-	old := vm.Debug
-
-	if len(call.ArgumentList) > 1 {
-		vm.Debug, _ = call.Argument(1).ToBoolean()
-	}
-
-	_, err = js.ethereum.BlockProcessor().RetryProcess(block)
-	if err != nil {
-		fmt.Println(err)
-		r, _ := call.Otto.ToValue(map[string]interface{}{"success": false, "time": time.Since(tstart).Seconds()})
-		return r
-	}
-	vm.Debug = old
-
-	r, _ := call.Otto.ToValue(map[string]interface{}{"success": true, "time": time.Since(tstart).Seconds()})
-	return r
-}
-
-func (js *jsre) insertBlockRlp(call otto.FunctionCall) otto.Value {
-	tstart := time.Now()
-
-	var block types.Block
-	if call.Argument(0).IsString() {
-		blockRlp, _ := call.Argument(0).ToString()
-		err := rlp.DecodeBytes(common.Hex2Bytes(blockRlp), &block)
-		if err != nil {
-			fmt.Println(err)
-			return otto.UndefinedValue()
-		}
-	}
-
-	old := vm.Debug
-	vm.Debug = true
-	_, err := js.ethereum.BlockProcessor().RetryProcess(&block)
-	if err != nil {
-		fmt.Println(err)
-		r, _ := call.Otto.ToValue(map[string]interface{}{"success": false, "time": time.Since(tstart).Seconds()})
-		return r
-	}
-	vm.Debug = old
-
-	r, _ := call.Otto.ToValue(map[string]interface{}{"success": true, "time": time.Since(tstart).Seconds()})
-	return r
-}
-
-func (js *jsre) setHead(call otto.FunctionCall) otto.Value {
-	block, err := js.getBlock(call)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	js.ethereum.ChainManager().SetHead(block)
-	return otto.UndefinedValue()
-}
-
-func (js *jsre) syncProgress(call otto.FunctionCall) otto.Value {
-	pending, cached, importing, eta := js.ethereum.Downloader().Stats()
-	v, _ := call.Otto.ToValue(map[string]interface{}{
-		"pending":   pending,
-		"cached":    cached,
-		"importing": importing,
-		"estimate":  (eta / time.Second * time.Second).String(),
-	})
-	return v
-}
-
-func (js *jsre) getBlockRlp(call otto.FunctionCall) otto.Value {
-	block, err := js.getBlock(call)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-	encoded, _ := rlp.EncodeToBytes(block)
-	v, _ := call.Otto.ToValue(fmt.Sprintf("%x", encoded))
-	return v
-}
-
-func (js *jsre) setExtra(call otto.FunctionCall) otto.Value {
-	extra, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	if len(extra) > 1024 {
-		fmt.Println("error: cannot exceed 1024 bytes")
-		return otto.UndefinedValue()
-	}
-
-	js.ethereum.Miner().SetExtra([]byte(extra))
-	return otto.UndefinedValue()
-}
-
-func (js *jsre) setGasPrice(call otto.FunctionCall) otto.Value {
-	gasPrice, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	js.ethereum.Miner().SetGasPrice(common.String2Big(gasPrice))
-	return otto.UndefinedValue()
-}
-
-func (js *jsre) hashrate(call otto.FunctionCall) otto.Value {
-	v, _ := call.Otto.ToValue(js.ethereum.Miner().HashRate())
-	return v
-}
-
-func (js *jsre) makeDAG(call otto.FunctionCall) otto.Value {
-	blockNumber, err := call.Argument(1).ToInteger()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	err = ethash.MakeDAG(uint64(blockNumber), "")
-	if err != nil {
-		return otto.FalseValue()
-	}
-	return otto.TrueValue()
-}
-
-func (js *jsre) startAutoDAG(otto.FunctionCall) otto.Value {
-	js.ethereum.StartAutoDAG()
-	return otto.TrueValue()
-}
-
-func (js *jsre) stopAutoDAG(otto.FunctionCall) otto.Value {
-	js.ethereum.StopAutoDAG()
-	return otto.TrueValue()
-}
-
-func (js *jsre) backtrace(call otto.FunctionCall) otto.Value {
-	tracestr, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-	glog.GetTraceLocation().Set(tracestr)
-
-	return otto.UndefinedValue()
-}
-
-func (js *jsre) verbosity(call otto.FunctionCall) otto.Value {
-	v, err := call.Argument(0).ToInteger()
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	glog.SetV(int(v))
-	return otto.UndefinedValue()
-}
-
-func (js *jsre) startMining(call otto.FunctionCall) otto.Value {
-	var (
-		threads int64
-		err     error
-	)
-
-	if len(call.ArgumentList) > 0 {
-		threads, err = call.Argument(0).ToInteger()
-		if err != nil {
-			fmt.Println(err)
-			return otto.FalseValue()
-		}
-	} else {
-		threads = int64(js.ethereum.MinerThreads)
-	}
-
-	// switch on DAG autogeneration when miner starts
-	js.ethereum.StartAutoDAG()
-
-	err = js.ethereum.StartMining(int(threads))
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	return otto.TrueValue()
-}
-
-func (js *jsre) stopMining(call otto.FunctionCall) otto.Value {
-	js.ethereum.StopMining()
-	js.ethereum.StopAutoDAG()
-	return otto.TrueValue()
-}
-
-func (js *jsre) startRPC(call otto.FunctionCall) otto.Value {
-	addr, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	port, err := call.Argument(1).ToInteger()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	corsDomain := js.corsDomain
-	if len(call.ArgumentList) > 2 {
-		corsDomain, err = call.Argument(2).ToString()
-		if err != nil {
-			fmt.Println(err)
-			return otto.FalseValue()
-		}
-	}
-
-	config := rpc.RpcConfig{
-		ListenAddress: addr,
-		ListenPort:    uint(port),
-		CorsDomain:    corsDomain,
-	}
-
-	xeth := xeth.New(js.ethereum, nil)
-	err = rpc.Start(xeth, config)
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	return otto.TrueValue()
-}
-
-func (js *jsre) stopRPC(call otto.FunctionCall) otto.Value {
-	if rpc.Stop() == nil {
-		return otto.TrueValue()
-	}
-	return otto.FalseValue()
-}
-
-func (js *jsre) addPeer(call otto.FunctionCall) otto.Value {
-	nodeURL, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-	err = js.ethereum.AddPeer(nodeURL)
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-	return otto.TrueValue()
-}
-
-func (js *jsre) unlock(call otto.FunctionCall) otto.Value {
-	addr, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-	seconds, err := call.Argument(2).ToInteger()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-	if seconds == 0 {
-		seconds = accounts.DefaultAccountUnlockDuration
-	}
-
-	arg := call.Argument(1)
-	var passphrase string
-	if arg.IsUndefined() {
-		fmt.Println("Please enter a passphrase now.")
-		passphrase, err = utils.PromptPassword("Passphrase: ", true)
-		if err != nil {
-			fmt.Println(err)
-			return otto.FalseValue()
-		}
-	} else {
-		passphrase, err = arg.ToString()
-		if err != nil {
-			fmt.Println(err)
-			return otto.FalseValue()
-		}
-	}
-	am := js.ethereum.AccountManager()
-	err = am.TimedUnlock(common.HexToAddress(addr), passphrase, time.Duration(seconds)*time.Second)
-	if err != nil {
-		fmt.Printf("Unlock account failed '%v'\n", err)
-		return otto.FalseValue()
-	}
-	return otto.TrueValue()
-}
-
-func (js *jsre) newAccount(call otto.FunctionCall) otto.Value {
-	arg := call.Argument(0)
-	var passphrase string
-	if arg.IsUndefined() {
-		fmt.Println("The new account will be encrypted with a passphrase.")
-		fmt.Println("Please enter a passphrase now.")
-		auth, err := utils.PromptPassword("Passphrase: ", true)
-		if err != nil {
-			fmt.Println(err)
-			return otto.FalseValue()
-		}
-		confirm, err := utils.PromptPassword("Repeat Passphrase: ", false)
-		if err != nil {
-			fmt.Println(err)
-			return otto.FalseValue()
-		}
-		if auth != confirm {
-			fmt.Println("Passphrases did not match.")
-			return otto.FalseValue()
-		}
-		passphrase = auth
-	} else {
-		var err error
-		passphrase, err = arg.ToString()
-		if err != nil {
-			fmt.Println(err)
-			return otto.FalseValue()
-		}
-	}
-	acct, err := js.ethereum.AccountManager().NewAccount(passphrase)
-	if err != nil {
-		fmt.Printf("Could not create the account: %v", err)
-		return otto.UndefinedValue()
-	}
-	v, _ := call.Otto.ToValue(acct.Address.Hex())
-	return v
-}
-
-func (js *jsre) nodeInfo(call otto.FunctionCall) otto.Value {
-	v, _ := call.Otto.ToValue(js.ethereum.NodeInfo())
-	return v
-}
-
-func (js *jsre) peers(call otto.FunctionCall) otto.Value {
-	v, _ := call.Otto.ToValue(js.ethereum.PeersInfo())
-	return v
-}
-
-func (js *jsre) importChain(call otto.FunctionCall) otto.Value {
-	if len(call.ArgumentList) == 0 {
-		fmt.Println("require file name. admin.importChain(filename)")
-		return otto.FalseValue()
-	}
-	fn, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-	if err := utils.ImportChain(js.ethereum.ChainManager(), fn); err != nil {
-		fmt.Println("Import error: ", err)
-		return otto.FalseValue()
-	}
-	return otto.TrueValue()
-}
-
-func (js *jsre) exportChain(call otto.FunctionCall) otto.Value {
-	if len(call.ArgumentList) == 0 {
-		fmt.Println("require file name: admin.exportChain(filename)")
-		return otto.FalseValue()
-	}
-
-	fn, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-	if err := utils.ExportChain(js.ethereum.ChainManager(), fn); err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-	return otto.TrueValue()
-}
-
-func (js *jsre) printBlock(call otto.FunctionCall) otto.Value {
-	block, err := js.getBlock(call)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	fmt.Println(block)
-
-	return otto.UndefinedValue()
-}
-
-func (js *jsre) dumpBlock(call otto.FunctionCall) otto.Value {
-	block, err := js.getBlock(call)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	statedb := state.New(block.Root(), js.ethereum.StateDb())
-	dump := statedb.RawDump()
-	v, _ := call.Otto.ToValue(dump)
-	return v
-}
-
-func (js *jsre) waitForBlocks(call otto.FunctionCall) otto.Value {
-	if len(call.ArgumentList) > 2 {
-		fmt.Println("requires 0, 1 or 2 arguments: admin.debug.waitForBlock(minHeight, timeout)")
-		return otto.FalseValue()
-	}
-	var n, timeout int64
-	var timer <-chan time.Time
-	var height *big.Int
-	var err error
-	args := len(call.ArgumentList)
-	if args == 2 {
-		timeout, err = call.Argument(1).ToInteger()
-		if err != nil {
-			fmt.Println(err)
-			return otto.UndefinedValue()
-		}
-		timer = time.NewTimer(time.Duration(timeout) * time.Second).C
-	}
-	if args >= 1 {
-		n, err = call.Argument(0).ToInteger()
-		if err != nil {
-			fmt.Println(err)
-			return otto.UndefinedValue()
-		}
-		height = big.NewInt(n)
-	}
-
-	if args == 0 {
-		height = js.xeth.CurrentBlock().Number()
-		height.Add(height, common.Big1)
-	}
-
-	wait := js.wait
-	js.wait <- height
-	select {
-	case <-timer:
-		// if times out make sure the xeth loop does not block
-		go func() {
-			select {
-			case wait <- nil:
-			case <-wait:
-			}
-		}()
-		return otto.UndefinedValue()
-	case height = <-wait:
-	}
-	v, _ := call.Otto.ToValue(height.Uint64())
-	return v
-}
-
-func (js *jsre) sleep(call otto.FunctionCall) otto.Value {
-	sec, err := call.Argument(0).ToInteger()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-	time.Sleep(time.Duration(sec) * time.Second)
-	return otto.UndefinedValue()
-}
-
-func (js *jsre) setSolc(call otto.FunctionCall) otto.Value {
-	if len(call.ArgumentList) != 1 {
-		fmt.Println("needs 1 argument: admin.contractInfo.setSolc(solcPath)")
-		return otto.FalseValue()
-	}
-	solcPath, err := call.Argument(0).ToString()
-	if err != nil {
-		return otto.FalseValue()
-	}
-	solc, err := js.xeth.SetSolc(solcPath)
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-	fmt.Println(solc.Info())
-	return otto.TrueValue()
-}
-
-func (js *jsre) register(call otto.FunctionCall) otto.Value {
-	if len(call.ArgumentList) != 4 {
-		fmt.Println("requires 4 arguments: admin.contractInfo.register(fromaddress, contractaddress, contract, filename)")
-		return otto.UndefinedValue()
-	}
-	sender, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	address, err := call.Argument(1).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	raw, err := call.Argument(2).Export()
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-	jsonraw, err := json.Marshal(raw)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-	var contract compiler.Contract
-	err = json.Unmarshal(jsonraw, &contract)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	filename, err := call.Argument(3).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	contenthash, err := compiler.ExtractInfo(&contract, filename)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-	// sender and contract address are passed as hex strings
-	codeb := js.xeth.CodeAtBytes(address)
-	codehash := common.BytesToHash(crypto.Sha3(codeb))
-
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	registry := resolver.New(js.xeth)
-
-	_, err = registry.RegisterContentHash(common.HexToAddress(sender), codehash, contenthash)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-
-	v, _ := call.Otto.ToValue(contenthash.Hex())
-	return v
-}
-
-func (js *jsre) registerUrl(call otto.FunctionCall) otto.Value {
-	if len(call.ArgumentList) != 3 {
-		fmt.Println("requires 3 arguments: admin.contractInfo.register(fromaddress, contenthash, filename)")
-		return otto.FalseValue()
-	}
-	sender, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	contenthash, err := call.Argument(1).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	url, err := call.Argument(2).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	registry := resolver.New(js.xeth)
-
-	_, err = registry.RegisterUrl(common.HexToAddress(sender), common.HexToHash(contenthash), url)
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	return otto.TrueValue()
-}
-
-func (js *jsre) getContractInfo(call otto.FunctionCall) otto.Value {
-	if len(call.ArgumentList) != 1 {
-		fmt.Println("requires 1 argument: admin.contractInfo.register(contractaddress)")
-		return otto.FalseValue()
-	}
-	addr, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	infoDoc, err := natspec.FetchDocsForContract(addr, js.xeth, ds)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-	var info compiler.ContractInfo
-	err = json.Unmarshal(infoDoc, &info)
-	if err != nil {
-		fmt.Println(err)
-		return otto.UndefinedValue()
-	}
-	v, _ := call.Otto.ToValue(info)
-	return v
-}
-
-func (js *jsre) startNatSpec(call otto.FunctionCall) otto.Value {
-	js.ethereum.NatSpec = true
-	return otto.TrueValue()
-}
-
-func (js *jsre) stopNatSpec(call otto.FunctionCall) otto.Value {
-	js.ethereum.NatSpec = false
-	return otto.TrueValue()
-}
-
-func (js *jsre) newRegistry(call otto.FunctionCall) otto.Value {
-
-	if len(call.ArgumentList) != 1 {
-		fmt.Println("requires 1 argument: admin.contractInfo.newRegistry(adminaddress)")
-		return otto.FalseValue()
-	}
-	addr, err := call.Argument(0).ToString()
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	registry := resolver.New(js.xeth)
-	err = registry.CreateContracts(common.HexToAddress(addr))
-	if err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	return otto.TrueValue()
-}
-
-// internal transaction type which will allow us to resend transactions  using `eth.resend`
-type tx struct {
-	tx *types.Transaction
-
-	To       string
-	From     string
-	Nonce    string
-	Value    string
-	Data     string
-	GasLimit string
-	GasPrice string
-}
-
-func newTx(t *types.Transaction) *tx {
-	from, _ := t.From()
-	var to string
-	if t := t.To(); t != nil {
-		to = t.Hex()
-	}
-
-	return &tx{
-		tx:       t,
-		To:       to,
-		From:     from.Hex(),
-		Value:    t.Amount.String(),
-		Nonce:    strconv.Itoa(int(t.Nonce())),
-		Data:     "0x" + common.Bytes2Hex(t.Data()),
-		GasLimit: t.GasLimit.String(),
-		GasPrice: t.GasPrice().String(),
-	}
-}
diff --git a/cmd/geth/js.go b/cmd/geth/js.go
index 7e6e10ca9b1982493859eb9f4379d21ce9761b79..01840ebd9bbd9c26610f2e1ef540fbb422bf04e4 100644
--- a/cmd/geth/js.go
+++ b/cmd/geth/js.go
@@ -26,6 +26,8 @@ import (
 	"path/filepath"
 	"strings"
 
+	"sort"
+
 	"github.com/ethereum/go-ethereum/cmd/utils"
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/docserver"
@@ -33,9 +35,13 @@ import (
 	"github.com/ethereum/go-ethereum/eth"
 	re "github.com/ethereum/go-ethereum/jsre"
 	"github.com/ethereum/go-ethereum/rpc"
+	"github.com/ethereum/go-ethereum/rpc/api"
+	"github.com/ethereum/go-ethereum/rpc/codec"
+	"github.com/ethereum/go-ethereum/rpc/comms"
 	"github.com/ethereum/go-ethereum/xeth"
 	"github.com/peterh/liner"
 	"github.com/robertkrimen/otto"
+	"github.com/ethereum/go-ethereum/rpc/shared"
 )
 
 type prompter interface {
@@ -70,10 +76,104 @@ type jsre struct {
 	ps1        string
 	atexit     func()
 	corsDomain string
+	client     comms.EthereumClient
 	prompter
 }
 
-func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain, ipcpath string, interactive bool, f xeth.Frontend) *jsre {
+var (
+	loadedModulesMethods map[string][]string
+)
+
+func keywordCompleter(line string) []string {
+	results := make([]string, 0)
+
+	if strings.Contains(line, ".") {
+		elements := strings.Split(line, ".")
+		if len(elements) == 2 {
+			module := elements[0]
+			partialMethod := elements[1]
+			if methods, found := loadedModulesMethods[module]; found {
+				for _, method := range methods {
+					if strings.HasPrefix(method, partialMethod) { // e.g. debug.se
+						results = append(results, module+"."+method)
+					}
+				}
+			}
+		}
+	} else {
+		for module, methods := range loadedModulesMethods {
+			if line == module { // user typed in full module name, show all methods
+				for _, method := range methods {
+					results = append(results, module+"."+method)
+				}
+			} else if strings.HasPrefix(module, line) { // partial method name, e.g. admi
+				results = append(results, module)
+			}
+		}
+	}
+	return results
+}
+
+func apiWordCompleter(line string, pos int) (head string, completions []string, tail string) {
+	if len(line) == 0 {
+		return "", nil, ""
+	}
+
+	i := 0
+	for i = pos - 1; i > 0; i-- {
+		if line[i] == '.' || (line[i] >= 'a' && line[i] <= 'z') || (line[i] >= 'A' && line[i] <= 'Z') {
+			continue
+		}
+		if i >= 3 && line[i] == '3' && line[i-3] == 'w' && line[i-2] == 'e' && line[i-1] == 'b' {
+			continue
+		}
+		i += 1
+		break
+	}
+
+	begin := line[:i]
+	keyword := line[i:pos]
+	end := line[pos:]
+
+	completionWords := keywordCompleter(keyword)
+	return begin, completionWords, end
+}
+
+func newLightweightJSRE(libPath string, client comms.EthereumClient, interactive bool, f xeth.Frontend) *jsre {
+	js := &jsre{ps1: "> "}
+	js.wait = make(chan *big.Int)
+	js.client = client
+
+	if f == nil {
+		f = js
+	}
+
+	// update state in separare forever blocks
+	js.re = re.New(libPath)
+	if err := js.apiBindings(f); err != nil {
+		utils.Fatalf("Unable to initialize console - %v", err)
+	}
+
+	if !liner.TerminalSupported() || !interactive {
+		js.prompter = dumbterm{bufio.NewReader(os.Stdin)}
+	} else {
+		lr := liner.NewLiner()
+		js.withHistory(func(hist *os.File) { lr.ReadHistory(hist) })
+		lr.SetCtrlCAborts(true)
+		js.loadAutoCompletion()
+		lr.SetWordCompleter(apiWordCompleter)
+		lr.SetTabCompletionStyle(liner.TabPrints)
+		js.prompter = lr
+		js.atexit = func() {
+			js.withHistory(func(hist *os.File) { hist.Truncate(0); lr.WriteHistory(hist) })
+			lr.Close()
+			close(js.wait)
+		}
+	}
+	return js
+}
+
+func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, client comms.EthereumClient, interactive bool, f xeth.Frontend) *jsre {
 	js := &jsre{ethereum: ethereum, ps1: "> "}
 	// set default cors domain used by startRpc from CLI flag
 	js.corsDomain = corsDomain
@@ -82,10 +182,18 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain, ipcpath string, intera
 	}
 	js.xeth = xeth.New(ethereum, f)
 	js.wait = js.xeth.UpdateState()
+	js.client = client
+	if clt, ok := js.client.(*comms.InProcClient); ok {
+		if offeredApis, err := api.ParseApiString(shared.AllApis, codec.JSON, js.xeth, ethereum); err == nil {
+			clt.Initialize(api.Merge(offeredApis...))
+		}
+	}
+
 	// update state in separare forever blocks
 	js.re = re.New(libPath)
-	js.apiBindings(ipcpath, f)
-	js.adminBindings()
+	if err := js.apiBindings(f); err != nil {
+		utils.Fatalf("Unable to connect - %v", err)
+	}
 
 	if !liner.TerminalSupported() || !interactive {
 		js.prompter = dumbterm{bufio.NewReader(os.Stdin)}
@@ -93,6 +201,9 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain, ipcpath string, intera
 		lr := liner.NewLiner()
 		js.withHistory(func(hist *os.File) { lr.ReadHistory(hist) })
 		lr.SetCtrlCAborts(true)
+		js.loadAutoCompletion()
+		lr.SetWordCompleter(apiWordCompleter)
+		lr.SetTabCompletionStyle(liner.TabPrints)
 		js.prompter = lr
 		js.atexit = func() {
 			js.withHistory(func(hist *os.File) { hist.Truncate(0); lr.WriteHistory(hist) })
@@ -103,11 +214,76 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain, ipcpath string, intera
 	return js
 }
 
-func (js *jsre) apiBindings(ipcpath string, f xeth.Frontend) {
-	xe := xeth.New(js.ethereum, f)
-	ethApi := rpc.NewEthereumApi(xe)
-	jeth := rpc.NewJeth(ethApi, js.re, ipcpath)
+func (self *jsre) loadAutoCompletion() {
+	if modules, err := self.supportedApis(); err == nil {
+		loadedModulesMethods = make(map[string][]string)
+		for module, _ := range modules {
+			loadedModulesMethods[module] = api.AutoCompletion[module]
+		}
+	}
+}
+
+func (self *jsre) batch(statement string) {
+	val, err := self.re.Run(statement)
+
+	if err != nil {
+		fmt.Printf("error: %v", err)
+	} else if val.IsDefined() && val.IsObject() {
+		obj, _ := self.re.Get("ret_result")
+		fmt.Printf("%v", obj)
+	} else if val.IsDefined() {
+		fmt.Printf("%v", val)
+	}
+
+	if self.atexit != nil {
+		self.atexit()
+	}
+
+	self.re.Stop(false)
+}
+
+// show summary of current geth instance
+func (self *jsre) welcome() {
+	self.re.Eval(`console.log('instance: ' + web3.version.client);`)
+	self.re.Eval(`console.log(' datadir: ' + admin.datadir);`)
+	self.re.Eval(`console.log("coinbase: " + eth.coinbase);`)
+	self.re.Eval(`var lastBlockTimestamp = 1000 * eth.getBlock(eth.blockNumber).timestamp`)
+	self.re.Eval(`console.log("at block: " + eth.blockNumber + " (" + new Date(lastBlockTimestamp).toLocaleDateString()
+		+ " " + new Date(lastBlockTimestamp).toLocaleTimeString() + ")");`)
+
+	if modules, err := self.supportedApis(); err == nil {
+		loadedModules := make([]string, 0)
+		for api, version := range modules {
+			loadedModules = append(loadedModules, fmt.Sprintf("%s:%s", api, version))
+		}
+		sort.Strings(loadedModules)
+
+		self.re.Eval(fmt.Sprintf("var modules = '%s';", strings.Join(loadedModules, " ")))
+		self.re.Eval(`console.log(" modules: " + modules);`)
+	}
+}
+
+func (self *jsre) supportedApis() (map[string]string, error) {
+	return self.client.SupportedModules()
+}
+
+func (js *jsre) apiBindings(f xeth.Frontend) error {
+	apis, err := js.supportedApis()
+	if err != nil {
+		return err
+	}
+
+	apiNames := make([]string, 0, len(apis))
+	for a, _ := range apis {
+		apiNames = append(apiNames, a)
+	}
+
+	apiImpl, err := api.ParseApiString(strings.Join(apiNames, ","), codec.JSON, js.xeth, js.ethereum)
+	if err != nil {
+		utils.Fatalf("Unable to determine supported api's: %v", err)
+	}
 
+	jeth := rpc.NewJeth(api.Merge(apiImpl...), js.re, js.client)
 	js.re.Set("jeth", struct{}{})
 	t, _ := js.re.Get("jeth")
 	jethObj := t.Object()
@@ -115,14 +291,14 @@ func (js *jsre) apiBindings(ipcpath string, f xeth.Frontend) {
 	jethObj.Set("send", jeth.Send)
 	jethObj.Set("sendAsync", jeth.Send)
 
-	err := js.re.Compile("bignumber.js", re.BigNumber_JS)
+	err = js.re.Compile("bignumber.js", re.BigNumber_JS)
 	if err != nil {
 		utils.Fatalf("Error loading bignumber.js: %v", err)
 	}
 
 	err = js.re.Compile("ethereum.js", re.Web3_JS)
 	if err != nil {
-		utils.Fatalf("Error loading ethereum.js: %v", err)
+		utils.Fatalf("Error loading web3.js: %v", err)
 	}
 
 	_, err = js.re.Eval("var web3 = require('web3');")
@@ -134,17 +310,29 @@ func (js *jsre) apiBindings(ipcpath string, f xeth.Frontend) {
 	if err != nil {
 		utils.Fatalf("Error setting web3 provider: %v", err)
 	}
-	_, err = js.re.Eval(`
-var eth = web3.eth;
-var shh = web3.shh;
-var db  = web3.db;
-var net = web3.net;
-  `)
+
+	// load only supported API's in javascript runtime
+	shortcuts := "var eth = web3.eth; "
+	for _, apiName := range apiNames {
+		if apiName == shared.Web3ApiName {
+			continue // manually mapped
+		}
+
+		if err = js.re.Compile(fmt.Sprintf("%s.js", apiName), api.Javascript(apiName)); err == nil {
+			shortcuts += fmt.Sprintf("var %s = web3.%s; ", apiName, apiName)
+		} else {
+			utils.Fatalf("Error loading %s.js: %v", apiName, err)
+		}
+	}
+
+	_, err = js.re.Eval(shortcuts)
+
 	if err != nil {
 		utils.Fatalf("Error setting namespaces: %v", err)
 	}
 
 	js.re.Eval(globalRegistrar + "registrar = GlobalRegistrar.at(\"" + globalRegistrarAddr + "\");")
+	return nil
 }
 
 var ds, _ = docserver.New("/")
@@ -234,7 +422,12 @@ func (self *jsre) interactive() {
 }
 
 func (self *jsre) withHistory(op func(*os.File)) {
-	hist, err := os.OpenFile(filepath.Join(self.ethereum.DataDir, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
+	datadir := common.DefaultDataDir()
+	if self.ethereum != nil {
+		datadir = self.ethereum.DataDir
+	}
+
+	hist, err := os.OpenFile(filepath.Join(datadir, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
 	if err != nil {
 		fmt.Printf("unable to open history file: %v\n", err)
 		return
diff --git a/cmd/geth/js_test.go b/cmd/geth/js_test.go
index 20bde01f348eafaa3151d6aa34d1d32466dec2f0..cfbe26bee56f14d2cff09ae26e20ae88146f6786 100644
--- a/cmd/geth/js_test.go
+++ b/cmd/geth/js_test.go
@@ -20,6 +20,8 @@ import (
 	"github.com/ethereum/go-ethereum/core/state"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/eth"
+	"github.com/ethereum/go-ethereum/rpc/comms"
+	"github.com/ethereum/go-ethereum/rpc/codec"
 )
 
 const (
@@ -105,7 +107,8 @@ func testJEthRE(t *testing.T) (string, *testjethre, *eth.Ethereum) {
 		t.Errorf("Error creating DocServer: %v", err)
 	}
 	tf := &testjethre{ds: ds, stateDb: ethereum.ChainManager().State().Copy()}
-	repl := newJSRE(ethereum, assetPath, "", "", false, tf)
+	client := comms.NewInProcClient(codec.JSON)
+	repl := newJSRE(ethereum, assetPath, "", client, false, tf)
 	tf.jsre = repl
 	return tmp, tf, ethereum
 }
@@ -125,7 +128,7 @@ func TestNodeInfo(t *testing.T) {
 	defer ethereum.Stop()
 	defer os.RemoveAll(tmp)
 	want := `{"DiscPort":0,"IP":"0.0.0.0","ListenAddr":"","Name":"test","NodeID":"4cb2fc32924e94277bf94b5e4c983beedb2eabd5a0bc941db32202735c6625d020ca14a5963d1738af43b6ac0a711d61b1a06de931a499fe2aa0b1a132a902b5","NodeUrl":"enode://4cb2fc32924e94277bf94b5e4c983beedb2eabd5a0bc941db32202735c6625d020ca14a5963d1738af43b6ac0a711d61b1a06de931a499fe2aa0b1a132a902b5@0.0.0.0:0","TCPPort":0,"Td":"131072"}`
-	checkEvalJSON(t, repl, `admin.nodeInfo()`, want)
+	checkEvalJSON(t, repl, `admin.nodeInfo`, want)
 }
 
 func TestAccounts(t *testing.T) {
@@ -139,7 +142,7 @@ func TestAccounts(t *testing.T) {
 	checkEvalJSON(t, repl, `eth.accounts`, `["`+testAddress+`"]`)
 	checkEvalJSON(t, repl, `eth.coinbase`, `"`+testAddress+`"`)
 
-	val, err := repl.re.Run(`admin.newAccount("password")`)
+	val, err := repl.re.Run(`personal.newAccount("password")`)
 	if err != nil {
 		t.Errorf("expected no error, got %v", err)
 	}
@@ -161,7 +164,7 @@ func TestBlockChain(t *testing.T) {
 	defer ethereum.Stop()
 	defer os.RemoveAll(tmp)
 	// get current block dump before export/import.
-	val, err := repl.re.Run("JSON.stringify(admin.debug.dumpBlock())")
+	val, err := repl.re.Run("JSON.stringify(debug.dumpBlock(eth.blockNumber))")
 	if err != nil {
 		t.Errorf("expected no error, got %v", err)
 	}
@@ -178,14 +181,14 @@ func TestBlockChain(t *testing.T) {
 
 	ethereum.ChainManager().Reset()
 
-	checkEvalJSON(t, repl, `admin.export(`+tmpfileq+`)`, `true`)
+	checkEvalJSON(t, repl, `admin.exportChain(`+tmpfileq+`)`, `true`)
 	if _, err := os.Stat(tmpfile); err != nil {
 		t.Fatal(err)
 	}
 
 	// check import, verify that dumpBlock gives the same result.
-	checkEvalJSON(t, repl, `admin.import(`+tmpfileq+`)`, `true`)
-	checkEvalJSON(t, repl, `admin.debug.dumpBlock()`, beforeExport)
+	checkEvalJSON(t, repl, `admin.importChain(`+tmpfileq+`)`, `true`)
+	checkEvalJSON(t, repl, `debug.dumpBlock(eth.blockNumber)`, beforeExport)
 }
 
 func TestMining(t *testing.T) {
@@ -207,7 +210,7 @@ func TestRPC(t *testing.T) {
 	defer ethereum.Stop()
 	defer os.RemoveAll(tmp)
 
-	checkEvalJSON(t, repl, `admin.startRPC("127.0.0.1", 5004)`, `true`)
+	checkEvalJSON(t, repl, `admin.startRPC("127.0.0.1", 5004, "*", "web3,eth,net")`, `true`)
 }
 
 func TestCheckTestAccountBalance(t *testing.T) {
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index 89aae43e5e8a364b2e7eefe0422eaf56d4f29f71..02ec63300795cc0cd6c182ab4facfc27220c6f5d 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -38,6 +38,8 @@ import (
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/eth"
 	"github.com/ethereum/go-ethereum/logger"
+	"github.com/ethereum/go-ethereum/rpc/codec"
+	"github.com/ethereum/go-ethereum/rpc/comms"
 	"github.com/mattn/go-colorable"
 	"github.com/mattn/go-isatty"
 )
@@ -202,6 +204,16 @@ nodes.
 The Geth console is an interactive shell for the JavaScript runtime environment
 which exposes a node admin interface as well as the Ðapp JavaScript API.
 See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console
+`},
+		{
+			Action: attach,
+			Name:   "attach",
+			Usage:  `Geth Console: interactive JavaScript environment (connect to node)`,
+			Description: `
+The Geth console is an interactive shell for the JavaScript runtime environment
+which exposes a node admin interface as well as the Ðapp JavaScript API.
+See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console.
+This command allows to open a console on a running geth node.
 `,
 		},
 		{
@@ -239,9 +251,11 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
 		utils.RPCEnabledFlag,
 		utils.RPCListenAddrFlag,
 		utils.RPCPortFlag,
+		utils.RpcApiFlag,
 		utils.IPCDisabledFlag,
 		utils.IPCApiFlag,
 		utils.IPCPathFlag,
+		utils.ExecFlag,
 		utils.WhisperEnabledFlag,
 		utils.VMDebugFlag,
 		utils.ProtocolVersionFlag,
@@ -294,6 +308,44 @@ func run(ctx *cli.Context) {
 	ethereum.WaitForShutdown()
 }
 
+func attach(ctx *cli.Context) {
+	// Wrap the standard output with a colorified stream (windows)
+	if isatty.IsTerminal(os.Stdout.Fd()) {
+		if pr, pw, err := os.Pipe(); err == nil {
+			go io.Copy(colorable.NewColorableStdout(), pr)
+			os.Stdout = pw
+		}
+	}
+
+	var client comms.EthereumClient
+	var err error
+	if ctx.Args().Present() {
+		client, err = comms.ClientFromEndpoint(ctx.Args().First(), codec.JSON)
+	} else {
+		cfg := comms.IpcConfig{
+			Endpoint: ctx.GlobalString(utils.IPCPathFlag.Name),
+		}
+		client, err = comms.NewIpcClient(cfg, codec.JSON)
+	}
+
+	if err != nil {
+		utils.Fatalf("Unable to attach to geth node - %v", err)
+	}
+
+	repl := newLightweightJSRE(
+		ctx.GlobalString(utils.JSpathFlag.Name),
+		client,
+		true,
+		nil)
+
+	if ctx.GlobalString(utils.ExecFlag.Name) != "" {
+		repl.batch(ctx.GlobalString(utils.ExecFlag.Name))
+	} else {
+		repl.welcome()
+		repl.interactive()
+	}
+}
+
 func console(ctx *cli.Context) {
 	// Wrap the standard output with a colorified stream (windows)
 	if isatty.IsTerminal(os.Stdout.Fd()) {
@@ -309,16 +361,24 @@ func console(ctx *cli.Context) {
 		utils.Fatalf("%v", err)
 	}
 
+	client := comms.NewInProcClient(codec.JSON)
+
 	startEth(ctx, ethereum)
 	repl := newJSRE(
 		ethereum,
-		ctx.String(utils.JSpathFlag.Name),
+		ctx.GlobalString(utils.JSpathFlag.Name),
 		ctx.GlobalString(utils.RPCCORSDomainFlag.Name),
-		utils.IpcSocketPath(ctx),
+		client,
 		true,
 		nil,
 	)
-	repl.interactive()
+
+	if ctx.GlobalString(utils.ExecFlag.Name) != "" {
+		repl.batch(ctx.GlobalString(utils.ExecFlag.Name))
+	} else {
+		repl.welcome()
+		repl.interactive()
+	}
 
 	ethereum.Stop()
 	ethereum.WaitForShutdown()
@@ -331,12 +391,13 @@ func execJSFiles(ctx *cli.Context) {
 		utils.Fatalf("%v", err)
 	}
 
+	client := comms.NewInProcClient(codec.JSON)
 	startEth(ctx, ethereum)
 	repl := newJSRE(
 		ethereum,
-		ctx.String(utils.JSpathFlag.Name),
+		ctx.GlobalString(utils.JSpathFlag.Name),
 		ctx.GlobalString(utils.RPCCORSDomainFlag.Name),
-		utils.IpcSocketPath(ctx),
+		client,
 		false,
 		nil,
 	)
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 696dbd142befe02e5a505365756694906dc9a96e..15a577a0700f6a976fa5d02bc2150000f02e5271 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -22,7 +22,6 @@ import (
 	"github.com/ethereum/go-ethereum/logger"
 	"github.com/ethereum/go-ethereum/logger/glog"
 	"github.com/ethereum/go-ethereum/p2p/nat"
-	"github.com/ethereum/go-ethereum/rpc"
 	"github.com/ethereum/go-ethereum/rpc/api"
 	"github.com/ethereum/go-ethereum/rpc/codec"
 	"github.com/ethereum/go-ethereum/rpc/comms"
@@ -209,20 +208,29 @@ var (
 		Usage: "Domain on which to send Access-Control-Allow-Origin header",
 		Value: "",
 	}
+	RpcApiFlag = cli.StringFlag{
+		Name:  "rpcapi",
+		Usage: "Specify the API's which are offered over the HTTP RPC interface",
+		Value: comms.DefaultHttpRpcApis,
+	}
 	IPCDisabledFlag = cli.BoolFlag{
 		Name:  "ipcdisable",
 		Usage: "Disable the IPC-RPC server",
 	}
 	IPCApiFlag = cli.StringFlag{
 		Name:  "ipcapi",
-		Usage: "Specify the API's which are offered over this interface",
-		Value: api.DefaultIpcApis,
+		Usage: "Specify the API's which are offered over the IPC interface",
+		Value: comms.DefaultIpcApis,
 	}
 	IPCPathFlag = DirectoryFlag{
 		Name:  "ipcpath",
 		Usage: "Filename for IPC socket/pipe",
 		Value: DirectoryString{common.DefaultIpcPath()},
 	}
+	ExecFlag = cli.StringFlag{
+		Name:  "exec",
+		Usage: "Execute javascript statement (only in combination with console/attach)",
+	}
 	// Network Settings
 	MaxPeersFlag = cli.IntFlag{
 		Name:  "maxpeers",
@@ -453,18 +461,25 @@ func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error {
 		return err
 	}
 
-	return comms.StartIpc(config, codec, apis...)
+	return comms.StartIpc(config, codec, api.Merge(apis...))
 }
 
 func StartRPC(eth *eth.Ethereum, ctx *cli.Context) error {
-	config := rpc.RpcConfig{
+	config := comms.HttpConfig{
 		ListenAddress: ctx.GlobalString(RPCListenAddrFlag.Name),
 		ListenPort:    uint(ctx.GlobalInt(RPCPortFlag.Name)),
 		CorsDomain:    ctx.GlobalString(RPCCORSDomainFlag.Name),
 	}
 
 	xeth := xeth.New(eth, nil)
-	return rpc.Start(xeth, config)
+	codec := codec.JSON
+
+	apis, err := api.ParseApiString(ctx.GlobalString(RpcApiFlag.Name), codec, xeth, eth)
+	if err != nil {
+		return err
+	}
+
+	return comms.StartHttp(config, codec, api.Merge(apis...))
 }
 
 func StartPProf(ctx *cli.Context) {
diff --git a/core/transaction_pool.go b/core/transaction_pool.go
index 5ebe3576bba672f70bca62ccfaae46342212c442..34a1733d71140ab265f107acad67412f7a55158d 100644
--- a/core/transaction_pool.go
+++ b/core/transaction_pool.go
@@ -149,7 +149,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
 		return ErrInvalidSender
 	}
 
-	// Make sure the account exist. Non existant accounts
+	// Make sure the account exist. Non existent accounts
 	// haven't got funds and well therefor never pass.
 	if !pool.currentState().HasAccount(from) {
 		return ErrNonExistentAccount
diff --git a/rpc/api.go b/rpc/api.go
deleted file mode 100644
index a344a82946a408f56d03245852960c68b70da386..0000000000000000000000000000000000000000
--- a/rpc/api.go
+++ /dev/null
@@ -1,646 +0,0 @@
-package rpc
-
-import (
-	"bytes"
-	"encoding/json"
-	"math/big"
-
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/core/vm"
-	"github.com/ethereum/go-ethereum/crypto"
-	"github.com/ethereum/go-ethereum/logger"
-	"github.com/ethereum/go-ethereum/logger/glog"
-	"github.com/ethereum/go-ethereum/xeth"
-)
-
-type EthereumApi struct {
-	eth *xeth.XEth
-}
-
-func NewEthereumApi(xeth *xeth.XEth) *EthereumApi {
-	api := &EthereumApi{
-		eth: xeth,
-	}
-
-	return api
-}
-
-func (api *EthereumApi) xeth() *xeth.XEth {
-	return api.eth
-}
-
-func (api *EthereumApi) xethAtStateNum(num int64) *xeth.XEth {
-	return api.xeth().AtStateNum(num)
-}
-
-func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
-	// Spec at https://github.com/ethereum/wiki/wiki/JSON-RPC
-	glog.V(logger.Debug).Infof("%s %s", req.Method, req.Params)
-
-	switch req.Method {
-	case "web3_sha3":
-		args := new(Sha3Args)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		*reply = common.ToHex(crypto.Sha3(common.FromHex(args.Data)))
-	case "web3_clientVersion":
-		*reply = api.xeth().ClientVersion()
-	case "net_version":
-		*reply = api.xeth().NetworkVersion()
-	case "net_listening":
-		*reply = api.xeth().IsListening()
-	case "net_peerCount":
-		*reply = newHexNum(api.xeth().PeerCount())
-	case "eth_protocolVersion":
-		*reply = api.xeth().EthVersion()
-	case "eth_coinbase":
-		*reply = newHexData(api.xeth().Coinbase())
-	case "eth_mining":
-		*reply = api.xeth().IsMining()
-	case "eth_gasPrice":
-		v := api.xeth().DefaultGasPrice()
-		*reply = newHexNum(v.Bytes())
-	case "eth_accounts":
-		*reply = api.xeth().Accounts()
-	case "eth_blockNumber":
-		v := api.xeth().CurrentBlock().Number()
-		*reply = newHexNum(v.Bytes())
-	case "eth_getBalance":
-		args := new(GetBalanceArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		*reply = api.xethAtStateNum(args.BlockNumber).BalanceAt(args.Address)
-		//v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance()
-		//*reply = common.ToHex(v.Bytes())
-	case "eth_getStorage", "eth_storageAt":
-		args := new(GetStorageArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		*reply = api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage()
-	case "eth_getStorageAt":
-		args := new(GetStorageAtArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		*reply = api.xethAtStateNum(args.BlockNumber).StorageAt(args.Address, args.Key)
-	case "eth_getTransactionCount":
-		args := new(GetTxCountArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		count := api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address)
-		*reply = newHexNum(big.NewInt(int64(count)).Bytes())
-	case "eth_getBlockTransactionCountByHash":
-		args := new(HashArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		block := NewBlockRes(api.xeth().EthBlockByHash(args.Hash), false)
-		if block == nil {
-			*reply = nil
-		} else {
-			*reply = newHexNum(big.NewInt(int64(len(block.Transactions))).Bytes())
-		}
-	case "eth_getBlockTransactionCountByNumber":
-		args := new(BlockNumArg)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		block := NewBlockRes(api.xeth().EthBlockByNumber(args.BlockNumber), false)
-		if block == nil {
-			*reply = nil
-			break
-		}
-
-		*reply = newHexNum(big.NewInt(int64(len(block.Transactions))).Bytes())
-	case "eth_getUncleCountByBlockHash":
-		args := new(HashArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		block := api.xeth().EthBlockByHash(args.Hash)
-		br := NewBlockRes(block, false)
-		if br == nil {
-			*reply = nil
-			break
-		}
-
-		*reply = newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes())
-	case "eth_getUncleCountByBlockNumber":
-		args := new(BlockNumArg)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		block := api.xeth().EthBlockByNumber(args.BlockNumber)
-		br := NewBlockRes(block, false)
-		if br == nil {
-			*reply = nil
-			break
-		}
-
-		*reply = newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes())
-
-	case "eth_getData", "eth_getCode":
-		args := new(GetDataArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		v := api.xethAtStateNum(args.BlockNumber).CodeAtBytes(args.Address)
-		*reply = newHexData(v)
-
-	case "eth_sign":
-		args := new(NewSigArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		v, err := api.xeth().Sign(args.From, args.Data, false)
-		if err != nil {
-			return err
-		}
-		*reply = v
-
-	case "eth_sendRawTransaction":
-		args := new(NewDataArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		v, err := api.xeth().PushTx(args.Data)
-		if err != nil {
-			return err
-		}
-		*reply = v
-
-	case "eth_sendTransaction", "eth_transact":
-		args := new(NewTxArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		// nonce may be nil ("guess" mode)
-		var nonce string
-		if args.Nonce != nil {
-			nonce = args.Nonce.String()
-		}
-
-		var gas string
-		if args.Gas == nil {
-			gas = ""
-		} else {
-			gas = args.Gas.String()
-		}
-
-		var gasprice string
-		if args.GasPrice == nil {
-			gasprice = ""
-		} else {
-			gasprice = args.GasPrice.String()
-		}
-
-		v, err := api.xeth().Transact(args.From, args.To, nonce, args.Value.String(), gas, gasprice, args.Data)
-		if err != nil {
-			return err
-		}
-		*reply = v
-	case "eth_estimateGas":
-		_, gas, err := api.doCall(req.Params)
-		if err != nil {
-			return err
-		}
-
-		// TODO unwrap the parent method's ToHex call
-		if len(gas) == 0 {
-			*reply = newHexNum(0)
-		} else {
-			*reply = newHexNum(gas)
-		}
-	case "eth_call":
-		v, _, err := api.doCall(req.Params)
-		if err != nil {
-			return err
-		}
-
-		// TODO unwrap the parent method's ToHex call
-		if v == "0x0" {
-			*reply = newHexData([]byte{})
-		} else {
-			*reply = newHexData(common.FromHex(v))
-		}
-	case "eth_flush":
-		return NewNotImplementedError(req.Method)
-	case "eth_getBlockByHash":
-		args := new(GetBlockByHashArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		block := api.xeth().EthBlockByHash(args.BlockHash)
-		br := NewBlockRes(block, args.IncludeTxs)
-
-		*reply = br
-	case "eth_getBlockByNumber":
-		args := new(GetBlockByNumberArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		block := api.xeth().EthBlockByNumber(args.BlockNumber)
-		br := NewBlockRes(block, args.IncludeTxs)
-		// If request was for "pending", nil nonsensical fields
-		if args.BlockNumber == -2 {
-			br.BlockHash = nil
-			br.BlockNumber = nil
-			br.Miner = nil
-			br.Nonce = nil
-			br.LogsBloom = nil
-		}
-		*reply = br
-	case "eth_getTransactionByHash":
-		args := new(HashArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		tx, bhash, bnum, txi := api.xeth().EthTransactionByHash(args.Hash)
-		if tx != nil {
-			v := NewTransactionRes(tx)
-			// if the blockhash is 0, assume this is a pending transaction
-			if bytes.Compare(bhash.Bytes(), bytes.Repeat([]byte{0}, 32)) != 0 {
-				v.BlockHash = newHexData(bhash)
-				v.BlockNumber = newHexNum(bnum)
-				v.TxIndex = newHexNum(txi)
-			}
-			*reply = v
-		}
-	case "eth_getTransactionByBlockHashAndIndex":
-		args := new(HashIndexArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		block := api.xeth().EthBlockByHash(args.Hash)
-		br := NewBlockRes(block, true)
-		if br == nil {
-			*reply = nil
-			break
-		}
-
-		if args.Index >= int64(len(br.Transactions)) || args.Index < 0 {
-			// return NewValidationError("Index", "does not exist")
-			*reply = nil
-		} else {
-			*reply = br.Transactions[args.Index]
-		}
-	case "eth_getTransactionByBlockNumberAndIndex":
-		args := new(BlockNumIndexArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		block := api.xeth().EthBlockByNumber(args.BlockNumber)
-		v := NewBlockRes(block, true)
-		if v == nil {
-			*reply = nil
-			break
-		}
-
-		if args.Index >= int64(len(v.Transactions)) || args.Index < 0 {
-			// return NewValidationError("Index", "does not exist")
-			*reply = nil
-		} else {
-			*reply = v.Transactions[args.Index]
-		}
-	case "eth_getUncleByBlockHashAndIndex":
-		args := new(HashIndexArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		br := NewBlockRes(api.xeth().EthBlockByHash(args.Hash), false)
-		if br == nil {
-			*reply = nil
-			return nil
-		}
-
-		if args.Index >= int64(len(br.Uncles)) || args.Index < 0 {
-			// return NewValidationError("Index", "does not exist")
-			*reply = nil
-		} else {
-			*reply = br.Uncles[args.Index]
-		}
-	case "eth_getUncleByBlockNumberAndIndex":
-		args := new(BlockNumIndexArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		block := api.xeth().EthBlockByNumber(args.BlockNumber)
-		v := NewBlockRes(block, true)
-
-		if v == nil {
-			*reply = nil
-			return nil
-		}
-
-		if args.Index >= int64(len(v.Uncles)) || args.Index < 0 {
-			// return NewValidationError("Index", "does not exist")
-			*reply = nil
-		} else {
-			*reply = v.Uncles[args.Index]
-		}
-
-	case "eth_getCompilers":
-		var lang string
-		if solc, _ := api.xeth().Solc(); solc != nil {
-			lang = "Solidity"
-		}
-		c := []string{lang}
-		*reply = c
-
-	case "eth_compileLLL", "eth_compileSerpent":
-		return NewNotImplementedError(req.Method)
-
-	case "eth_compileSolidity":
-		solc, _ := api.xeth().Solc()
-		if solc == nil {
-			return NewNotAvailableError(req.Method, "solc (solidity compiler) not found")
-		}
-
-		args := new(SourceArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		contracts, err := solc.Compile(args.Source)
-		if err != nil {
-			return err
-		}
-		*reply = contracts
-
-	case "eth_newFilter":
-		args := new(BlockFilterArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		id := api.xeth().NewLogFilter(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)
-		*reply = newHexNum(big.NewInt(int64(id)).Bytes())
-
-	case "eth_newBlockFilter":
-		*reply = newHexNum(api.xeth().NewBlockFilter())
-	case "eth_newPendingTransactionFilter":
-		*reply = newHexNum(api.xeth().NewTransactionFilter())
-	case "eth_uninstallFilter":
-		args := new(FilterIdArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		*reply = api.xeth().UninstallFilter(args.Id)
-	case "eth_getFilterChanges":
-		args := new(FilterIdArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		switch api.xeth().GetFilterType(args.Id) {
-		case xeth.BlockFilterTy:
-			*reply = NewHashesRes(api.xeth().BlockFilterChanged(args.Id))
-		case xeth.TransactionFilterTy:
-			*reply = NewHashesRes(api.xeth().TransactionFilterChanged(args.Id))
-		case xeth.LogFilterTy:
-			*reply = NewLogsRes(api.xeth().LogFilterChanged(args.Id))
-		default:
-			*reply = []string{} // reply empty string slice
-		}
-	case "eth_getFilterLogs":
-		args := new(FilterIdArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		*reply = NewLogsRes(api.xeth().Logs(args.Id))
-	case "eth_getLogs":
-		args := new(BlockFilterArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		*reply = NewLogsRes(api.xeth().AllLogs(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics))
-	case "eth_getWork":
-		api.xeth().SetMining(true, 0)
-		*reply = api.xeth().RemoteMining().GetWork()
-	case "eth_submitWork":
-		args := new(SubmitWorkArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		*reply = api.xeth().RemoteMining().SubmitWork(args.Nonce, common.HexToHash(args.Digest), common.HexToHash(args.Header))
-	case "db_putString":
-		args := new(DbArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		if err := args.requirements(); err != nil {
-			return err
-		}
-
-		api.xeth().DbPut([]byte(args.Database+args.Key), args.Value)
-
-		*reply = true
-	case "db_getString":
-		args := new(DbArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		if err := args.requirements(); err != nil {
-			return err
-		}
-
-		res, _ := api.xeth().DbGet([]byte(args.Database + args.Key))
-		*reply = string(res)
-	case "db_putHex":
-		args := new(DbHexArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		if err := args.requirements(); err != nil {
-			return err
-		}
-
-		api.xeth().DbPut([]byte(args.Database+args.Key), args.Value)
-		*reply = true
-	case "db_getHex":
-		args := new(DbHexArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		if err := args.requirements(); err != nil {
-			return err
-		}
-
-		res, _ := api.xeth().DbGet([]byte(args.Database + args.Key))
-		*reply = newHexData(res)
-
-	case "shh_version":
-		// Short circuit if whisper is not running
-		if api.xeth().Whisper() == nil {
-			return NewNotAvailableError(req.Method, "whisper offline")
-		}
-		// Retrieves the currently running whisper protocol version
-		*reply = api.xeth().WhisperVersion()
-
-	case "shh_post":
-		// Short circuit if whisper is not running
-		if api.xeth().Whisper() == nil {
-			return NewNotAvailableError(req.Method, "whisper offline")
-		}
-		// Injects a new message into the whisper network
-		args := new(WhisperMessageArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		err := api.xeth().Whisper().Post(args.Payload, args.To, args.From, args.Topics, args.Priority, args.Ttl)
-		if err != nil {
-			return err
-		}
-		*reply = true
-
-	case "shh_newIdentity":
-		// Short circuit if whisper is not running
-		if api.xeth().Whisper() == nil {
-			return NewNotAvailableError(req.Method, "whisper offline")
-		}
-		// Creates a new whisper identity to use for sending/receiving messages
-		*reply = api.xeth().Whisper().NewIdentity()
-
-	case "shh_hasIdentity":
-		// Short circuit if whisper is not running
-		if api.xeth().Whisper() == nil {
-			return NewNotAvailableError(req.Method, "whisper offline")
-		}
-		// Checks if an identity if owned or not
-		args := new(WhisperIdentityArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		*reply = api.xeth().Whisper().HasIdentity(args.Identity)
-
-	case "shh_newFilter":
-		// Short circuit if whisper is not running
-		if api.xeth().Whisper() == nil {
-			return NewNotAvailableError(req.Method, "whisper offline")
-		}
-		// Create a new filter to watch and match messages with
-		args := new(WhisperFilterArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		id := api.xeth().NewWhisperFilter(args.To, args.From, args.Topics)
-		*reply = newHexNum(big.NewInt(int64(id)).Bytes())
-
-	case "shh_uninstallFilter":
-		// Short circuit if whisper is not running
-		if api.xeth().Whisper() == nil {
-			return NewNotAvailableError(req.Method, "whisper offline")
-		}
-		// Remove an existing filter watching messages
-		args := new(FilterIdArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		*reply = api.xeth().UninstallWhisperFilter(args.Id)
-
-	case "shh_getFilterChanges":
-		// Short circuit if whisper is not running
-		if api.xeth().Whisper() == nil {
-			return NewNotAvailableError(req.Method, "whisper offline")
-		}
-		// Retrieve all the new messages arrived since the last request
-		args := new(FilterIdArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		*reply = api.xeth().WhisperMessagesChanged(args.Id)
-
-	case "shh_getMessages":
-		// Short circuit if whisper is not running
-		if api.xeth().Whisper() == nil {
-			return NewNotAvailableError(req.Method, "whisper offline")
-		}
-		// Retrieve all the cached messages matching a specific, existing filter
-		args := new(FilterIdArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-		*reply = api.xeth().WhisperMessages(args.Id)
-
-	case "eth_hashrate":
-		*reply = newHexNum(api.xeth().HashRate())
-	case "ext_disasm":
-		args := new(SourceArgs)
-		if err := json.Unmarshal(req.Params, &args); err != nil {
-			return err
-		}
-
-		*reply = vm.Disasm(common.FromHex(args.Source))
-
-	// case "eth_register":
-	// 	// Placeholder for actual type
-	// 	args := new(HashIndexArgs)
-	// 	if err := json.Unmarshal(req.Params, &args); err != nil {
-	// 		return err
-	// 	}
-	// 	*reply = api.xeth().Register(args.Hash)
-	// case "eth_unregister":
-	// 	args := new(HashIndexArgs)
-	// 	if err := json.Unmarshal(req.Params, &args); err != nil {
-	// 		return err
-	// 	}
-	// 	*reply = api.xeth().Unregister(args.Hash)
-	// case "eth_watchTx":
-	// 	args := new(HashIndexArgs)
-	// 	if err := json.Unmarshal(req.Params, &args); err != nil {
-	// 		return err
-	// 	}
-	// 	*reply = api.xeth().PullWatchTx(args.Hash)
-	default:
-		return NewNotImplementedError(req.Method)
-	}
-
-	// glog.V(logger.Detail).Infof("Reply: %v\n", reply)
-	return nil
-}
-
-func (api *EthereumApi) doCall(params json.RawMessage) (string, string, error) {
-	args := new(CallArgs)
-	if err := json.Unmarshal(params, &args); err != nil {
-		return "", "", err
-	}
-
-	var gas string
-	if args.Gas == nil {
-		gas = ""
-	} else {
-		gas = args.Gas.String()
-	}
-
-	var gasprice string
-	if args.GasPrice == nil {
-		gasprice = ""
-	} else {
-		gasprice = args.GasPrice.String()
-	}
-
-	return api.xethAtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), gas, gasprice, args.Data)
-}
diff --git a/rpc/api/admin.go b/rpc/api/admin.go
index a6b9cf0502d57a7f0225b278f60bbe59c2f20621..b27482cfea5166e7d81e086942b67c526ad9aec7 100644
--- a/rpc/api/admin.go
+++ b/rpc/api/admin.go
@@ -11,6 +11,7 @@ import (
 	"github.com/ethereum/go-ethereum/logger/glog"
 	"github.com/ethereum/go-ethereum/rlp"
 	"github.com/ethereum/go-ethereum/rpc/codec"
+	"github.com/ethereum/go-ethereum/rpc/comms"
 	"github.com/ethereum/go-ethereum/rpc/shared"
 	"github.com/ethereum/go-ethereum/xeth"
 )
@@ -23,8 +24,6 @@ const (
 var (
 	// mapping between methods and handlers
 	AdminMapping = map[string]adminhandler{
-		//		"admin_startRPC": (*adminApi).StartRPC,
-		//		"admin_stopRPC":  (*adminApi).StopRPC,
 		"admin_addPeer":         (*adminApi).AddPeer,
 		"admin_peers":           (*adminApi).Peers,
 		"admin_nodeInfo":        (*adminApi).NodeInfo,
@@ -34,6 +33,8 @@ var (
 		"admin_chainSyncStatus": (*adminApi).ChainSyncStatus,
 		"admin_setSolc":         (*adminApi).SetSolc,
 		"admin_datadir":         (*adminApi).DataDir,
+		"admin_startRPC":        (*adminApi).StartRPC,
+		"admin_stopRPC":         (*adminApi).StopRPC,
 	}
 )
 
@@ -44,25 +45,25 @@ type adminhandler func(*adminApi, *shared.Request) (interface{}, error)
 type adminApi struct {
 	xeth     *xeth.XEth
 	ethereum *eth.Ethereum
-	methods  map[string]adminhandler
-	codec    codec.ApiCoder
+	codec    codec.Codec
+	coder    codec.ApiCoder
 }
 
 // create a new admin api instance
-func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *adminApi {
+func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, codec codec.Codec) *adminApi {
 	return &adminApi{
 		xeth:     xeth,
 		ethereum: ethereum,
-		methods:  AdminMapping,
-		codec:    coder.New(nil),
+		codec:    codec,
+		coder:    codec.New(nil),
 	}
 }
 
 // collection with supported methods
 func (self *adminApi) Methods() []string {
-	methods := make([]string, len(self.methods))
+	methods := make([]string, len(AdminMapping))
 	i := 0
-	for k := range self.methods {
+	for k := range AdminMapping {
 		methods[i] = k
 		i++
 	}
@@ -71,7 +72,7 @@ func (self *adminApi) Methods() []string {
 
 // Execute given request
 func (self *adminApi) Execute(req *shared.Request) (interface{}, error) {
-	if callback, ok := self.methods[req.Method]; ok {
+	if callback, ok := AdminMapping[req.Method]; ok {
 		return callback(self, req)
 	}
 
@@ -79,7 +80,7 @@ func (self *adminApi) Execute(req *shared.Request) (interface{}, error) {
 }
 
 func (self *adminApi) Name() string {
-	return AdminApiName
+	return shared.AdminApiName
 }
 
 func (self *adminApi) ApiVersion() string {
@@ -88,7 +89,7 @@ func (self *adminApi) ApiVersion() string {
 
 func (self *adminApi) AddPeer(req *shared.Request) (interface{}, error) {
 	args := new(AddPeerArgs)
-	if err := self.codec.Decode(req.Params, &args); err != nil {
+	if err := self.coder.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
 	}
 
@@ -103,33 +104,6 @@ func (self *adminApi) Peers(req *shared.Request) (interface{}, error) {
 	return self.ethereum.PeersInfo(), nil
 }
 
-func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) {
-	return false, nil
-	//	Enable when http rpc interface is refactored to prevent import cycles
-	//	args := new(StartRpcArgs)
-	//	if err := self.codec.Decode(req.Params, &args); err != nil {
-	//		return nil, shared.NewDecodeParamError(err.Error())
-	//	}
-	//
-	//	cfg := rpc.RpcConfig{
-	//		ListenAddress: args.Address,
-	//		ListenPort:    args.Port,
-	//	}
-	//
-	//	err := rpc.Start(self.xeth, cfg)
-	//	if err == nil {
-	//		return true, nil
-	//	}
-	//	return false, err
-}
-
-func (self *adminApi) StopRPC(req *shared.Request) (interface{}, error) {
-	return false, nil
-	//	Enable when http rpc interface is refactored to prevent import cycles
-	//	rpc.Stop()
-	//	return true, nil
-}
-
 func (self *adminApi) NodeInfo(req *shared.Request) (interface{}, error) {
 	return self.ethereum.NodeInfo(), nil
 }
@@ -149,7 +123,7 @@ func hasAllBlocks(chain *core.ChainManager, bs []*types.Block) bool {
 
 func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) {
 	args := new(ImportExportChainArgs)
-	if err := self.codec.Decode(req.Params, &args); err != nil {
+	if err := self.coder.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
 	}
 
@@ -192,7 +166,7 @@ func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) {
 
 func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) {
 	args := new(ImportExportChainArgs)
-	if err := self.codec.Decode(req.Params, &args); err != nil {
+	if err := self.coder.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
 	}
 
@@ -210,7 +184,7 @@ func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) {
 
 func (self *adminApi) Verbosity(req *shared.Request) (interface{}, error) {
 	args := new(VerbosityArgs)
-	if err := self.codec.Decode(req.Params, &args); err != nil {
+	if err := self.coder.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
 	}
 
@@ -222,16 +196,16 @@ func (self *adminApi) ChainSyncStatus(req *shared.Request) (interface{}, error)
 	pending, cached, importing, estimate := self.ethereum.Downloader().Stats()
 
 	return map[string]interface{}{
-		"blocksAvailable": pending,
+		"blocksAvailable":        pending,
 		"blocksWaitingForImport": cached,
-		"importing": importing,
-		"estimate": estimate.String(),
+		"importing":              importing,
+		"estimate":               estimate.String(),
 	}, nil
 }
 
 func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) {
 	args := new(SetSolcArgs)
-	if err := self.codec.Decode(req.Params, &args); err != nil {
+	if err := self.coder.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
 	}
 
@@ -241,3 +215,32 @@ func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) {
 	}
 	return solc.Info(), nil
 }
+
+func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) {
+	args := new(StartRPCArgs)
+	if err := self.coder.Decode(req.Params, &args); err != nil {
+		return nil, shared.NewDecodeParamError(err.Error())
+	}
+
+	cfg := comms.HttpConfig{
+		ListenAddress: args.ListenAddress,
+		ListenPort:    args.ListenPort,
+		CorsDomain:    args.CorsDomain,
+	}
+
+	apis, err := ParseApiString(args.Apis, self.codec, self.xeth, self.ethereum)
+	if err != nil {
+		return false, err
+	}
+
+	err = comms.StartHttp(cfg, self.codec, Merge(apis...))
+	if err == nil {
+		return true, nil
+	}
+	return false, err
+}
+
+func (self *adminApi) StopRPC(req *shared.Request) (interface{}, error) {
+	comms.StopHttp()
+	return true, nil
+}
diff --git a/rpc/api/admin_args.go b/rpc/api/admin_args.go
index 56bb57e201393a0f684a0545b0dc81a21e80003a..5437971caa04c357d0e15fab9bf15d6c3349bd75 100644
--- a/rpc/api/admin_args.go
+++ b/rpc/api/admin_args.go
@@ -95,3 +95,55 @@ func (args *SetSolcArgs) UnmarshalJSON(b []byte) (err error) {
 
 	return shared.NewInvalidTypeError("path", "not a string")
 }
+
+type StartRPCArgs struct {
+	ListenAddress string
+	ListenPort    uint
+	CorsDomain    string
+	Apis          string
+}
+
+func (args *StartRPCArgs) UnmarshalJSON(b []byte) (err error) {
+	var obj []interface{}
+	if err := json.Unmarshal(b, &obj); err != nil {
+		return shared.NewDecodeParamError(err.Error())
+	}
+
+	args.ListenAddress = "127.0.0.1"
+	args.ListenPort = 8545
+	args.Apis = "net,eth,web3"
+
+	if len(obj) >= 1 {
+		if addr, ok := obj[0].(string); ok {
+			args.ListenAddress = addr
+		} else {
+			return shared.NewInvalidTypeError("listenAddress", "not a string")
+		}
+	}
+
+	if len(obj) >= 2 {
+		if port, ok := obj[1].(float64); ok && port >= 0 && port <= 64*1024 {
+			args.ListenPort = uint(port)
+		} else {
+			return shared.NewInvalidTypeError("listenPort", "not a valid port number")
+		}
+	}
+
+	if len(obj) >= 3 {
+		if corsDomain, ok := obj[2].(string); ok {
+			args.CorsDomain = corsDomain
+		} else {
+			return shared.NewInvalidTypeError("corsDomain", "not a string")
+		}
+	}
+
+	if len(obj) >= 4 {
+		if apis, ok := obj[3].(string); ok {
+			args.Apis = apis
+		} else {
+			return shared.NewInvalidTypeError("apis", "not a string")
+		}
+	}
+
+	return nil
+}
diff --git a/rpc/api/admin_js.go b/rpc/api/admin_js.go
index c3e713c67d5f25d34233c2f53cc702c6ce43e850..97642ade71df59682915f88b5218bc4ea622f52a 100644
--- a/rpc/api/admin_js.go
+++ b/rpc/api/admin_js.go
@@ -39,6 +39,20 @@ web3._extend({
 			params: 1,
 			inputFormatter: [web3._extend.utils.formatInputString],
 			outputFormatter: web3._extend.formatters.formatOutputString
+		}),
+		new web3._extend.Method({
+			name: 'startRPC',
+			call: 'admin_startRPC',
+			params: 4,
+			inputFormatter: [web3._extend.utils.formatInputString,web3._extend.utils.formatInputInteger,web3._extend.utils.formatInputString,web3._extend.utils.formatInputString],
+			outputFormatter: web3._extend.formatters.formatOutputBool
+		}),
+		new web3._extend.Method({
+			name: 'stopRPC',
+			call: 'admin_stopRPC',
+			params: 0,
+			inputFormatter: [],
+			outputFormatter: web3._extend.formatters.formatOutputBool
 		})
 	],
 	properties:
diff --git a/rpc/api/api.go b/rpc/api/api.go
index e431e5c1ef87fb4080c4400ae518fb0a92eebae6..ca1ccb9a54251a6f098d64bb6a0fd43f3fb95dca 100644
--- a/rpc/api/api.go
+++ b/rpc/api/api.go
@@ -1,48 +1,10 @@
 package api
 
 import (
-	"strings"
-
 	"github.com/ethereum/go-ethereum/rpc/shared"
 )
 
-const (
-	AdminApiName    = "admin"
-	EthApiName      = "eth"
-	DebugApiName    = "debug"
-	MergedApiName   = "merged"
-	MinerApiName    = "miner"
-	NetApiName      = "net"
-	ShhApiName      = "shh"
-	TxPoolApiName   = "txpool"
-	PersonalApiName = "personal"
-	Web3ApiName     = "web3"
-)
-
-var (
-	// List with all API's which are offered over the IPC interface by default
-	DefaultIpcApis = strings.Join([]string{
-		AdminApiName, EthApiName, DebugApiName, MinerApiName, NetApiName,
-		ShhApiName, TxPoolApiName, PersonalApiName, Web3ApiName,
-	}, ",")
-)
-
-// Ethereum RPC API interface
-type EthereumApi interface {
-	// API identifier
-	Name() string
-
-	// API version
-	ApiVersion() string
-
-	// Execute the given request and returns the response or an error
-	Execute(*shared.Request) (interface{}, error)
-
-	// List of supported RCP methods this API provides
-	Methods() []string
-}
-
 // Merge multiple API's to a single API instance
-func Merge(apis ...EthereumApi) EthereumApi {
+func Merge(apis ...shared.EthereumApi) shared.EthereumApi {
 	return newMergedApi(apis...)
 }
diff --git a/rpc/api/api_test.go b/rpc/api/api_test.go
index f1a47944dbbc7ba4aac64505eed0031cfa9aee90..7e273ef28fd7fa87b17e0d35e2f712572f5d5e05 100644
--- a/rpc/api/api_test.go
+++ b/rpc/api/api_test.go
@@ -3,7 +3,14 @@ package api
 import (
 	"testing"
 
+	"encoding/json"
+	"strconv"
+
+	"github.com/ethereum/go-ethereum/common/compiler"
+	"github.com/ethereum/go-ethereum/eth"
 	"github.com/ethereum/go-ethereum/rpc/codec"
+	"github.com/ethereum/go-ethereum/rpc/shared"
+	"github.com/ethereum/go-ethereum/xeth"
 )
 
 func TestParseApiString(t *testing.T) {
@@ -40,3 +47,107 @@ func TestParseApiString(t *testing.T) {
 	}
 
 }
+
+const solcVersion = "0.9.23"
+
+func TestCompileSolidity(t *testing.T) {
+
+	solc, err := compiler.New("")
+	if solc == nil {
+		t.Skip("no solc found: skip")
+	} else if solc.Version() != solcVersion {
+		t.Skip("WARNING: skipping test because of solc different version (%v, test written for %v, may need to update)", solc.Version(), solcVersion)
+	}
+	source := `contract test {\n` +
+		"   /// @notice Will multiply `a` by 7." + `\n` +
+		`   function multiply(uint a) returns(uint d) {\n` +
+		`       return a * 7;\n` +
+		`   }\n` +
+		`}\n`
+
+	jsonstr := `{"jsonrpc":"2.0","method":"eth_compileSolidity","params":["` + source + `"],"id":64}`
+
+	expCode := "0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056"
+	expAbiDefinition := `[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]`
+	expUserDoc := `{"methods":{"multiply(uint256)":{"notice":"Will multiply ` + "`a`" + ` by 7."}}}`
+	expDeveloperDoc := `{"methods":{}}`
+	expCompilerVersion := solc.Version()
+	expLanguage := "Solidity"
+	expLanguageVersion := "0"
+	expSource := source
+
+	xeth := xeth.NewTest(&eth.Ethereum{}, nil)
+	api := NewEthApi(xeth, codec.JSON)
+
+	var rpcRequest shared.Request
+	json.Unmarshal([]byte(jsonstr), &rpcRequest)
+
+	response, err := api.CompileSolidity(&rpcRequest)
+	if err != nil {
+		t.Errorf("Execution failed, %v", err)
+	}
+
+	respjson, err := json.Marshal(response)
+	if err != nil {
+		t.Errorf("expected no error, got %v", err)
+	}
+
+	var contracts = make(map[string]*compiler.Contract)
+	err = json.Unmarshal(respjson, &contracts)
+	if err != nil {
+		t.Errorf("expected no error, got %v", err)
+	}
+
+	if len(contracts) != 1 {
+		t.Errorf("expected one contract, got %v", len(contracts))
+	}
+
+	contract := contracts["test"]
+
+	if contract.Code != expCode {
+		t.Errorf("Expected \n%s got \n%s", expCode, contract.Code)
+	}
+
+	if strconv.Quote(contract.Info.Source) != `"`+expSource+`"` {
+		t.Errorf("Expected \n'%s' got \n'%s'", expSource, strconv.Quote(contract.Info.Source))
+	}
+
+	if contract.Info.Language != expLanguage {
+		t.Errorf("Expected %s got %s", expLanguage, contract.Info.Language)
+	}
+
+	if contract.Info.LanguageVersion != expLanguageVersion {
+		t.Errorf("Expected %s got %s", expLanguageVersion, contract.Info.LanguageVersion)
+	}
+
+	if contract.Info.CompilerVersion != expCompilerVersion {
+		t.Errorf("Expected %s got %s", expCompilerVersion, contract.Info.CompilerVersion)
+	}
+
+	userdoc, err := json.Marshal(contract.Info.UserDoc)
+	if err != nil {
+		t.Errorf("expected no error, got %v", err)
+	}
+
+	devdoc, err := json.Marshal(contract.Info.DeveloperDoc)
+	if err != nil {
+		t.Errorf("expected no error, got %v", err)
+	}
+
+	abidef, err := json.Marshal(contract.Info.AbiDefinition)
+	if err != nil {
+		t.Errorf("expected no error, got %v", err)
+	}
+
+	if string(abidef) != expAbiDefinition {
+		t.Errorf("Expected \n'%s' got \n'%s'", expAbiDefinition, string(abidef))
+	}
+
+	if string(userdoc) != expUserDoc {
+		t.Errorf("Expected \n'%s' got \n'%s'", expUserDoc, string(userdoc))
+	}
+
+	if string(devdoc) != expDeveloperDoc {
+		t.Errorf("Expected %s got %s", expDeveloperDoc, string(devdoc))
+	}
+}
diff --git a/rpc/api/args.go b/rpc/api/args.go
new file mode 100644
index 0000000000000000000000000000000000000000..fc85448e655ebd9ff89752e025f7cc583d340845
--- /dev/null
+++ b/rpc/api/args.go
@@ -0,0 +1,58 @@
+package api
+
+import (
+	"encoding/json"
+
+	"github.com/ethereum/go-ethereum/rpc/shared"
+)
+
+type CompileArgs struct {
+	Source string
+}
+
+func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) {
+	var obj []interface{}
+	if err := json.Unmarshal(b, &obj); err != nil {
+		return shared.NewDecodeParamError(err.Error())
+	}
+
+	if len(obj) < 1 {
+		return shared.NewInsufficientParamsError(len(obj), 1)
+	}
+	argstr, ok := obj[0].(string)
+	if !ok {
+		return shared.NewInvalidTypeError("arg0", "is not a string")
+	}
+	args.Source = argstr
+
+	return nil
+}
+
+type FilterStringArgs struct {
+	Word string
+}
+
+func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
+	var obj []interface{}
+	if err := json.Unmarshal(b, &obj); err != nil {
+		return shared.NewDecodeParamError(err.Error())
+	}
+
+	if len(obj) < 1 {
+		return shared.NewInsufficientParamsError(len(obj), 1)
+	}
+
+	var argstr string
+	argstr, ok := obj[0].(string)
+	if !ok {
+		return shared.NewInvalidTypeError("filter", "not a string")
+	}
+	switch argstr {
+	case "latest", "pending":
+		break
+	default:
+		return shared.NewValidationError("Word", "Must be `latest` or `pending`")
+	}
+	args.Word = argstr
+	return nil
+}
diff --git a/rpc/args_test.go b/rpc/api/args_test.go
similarity index 99%
rename from rpc/args_test.go
rename to rpc/api/args_test.go
index fd20dbab8bf359ac4509e37892671151a2bd40e8..a30f247bca92e4b433dd8aaf8ca58e9938fabf48 100644
--- a/rpc/args_test.go
+++ b/rpc/api/args_test.go
@@ -1,4 +1,4 @@
-package rpc
+package api
 
 import (
 	"bytes"
@@ -6,6 +6,8 @@ import (
 	"fmt"
 	"math/big"
 	"testing"
+
+	"github.com/ethereum/go-ethereum/rpc/shared"
 )
 
 func TestBlockheightInvalidString(t *testing.T) {
@@ -68,7 +70,7 @@ func ExpectValidationError(err error) string {
 	switch err.(type) {
 	case nil:
 		str = "Expected error but didn't get one"
-	case *ValidationError:
+	case *shared.ValidationError:
 		break
 	default:
 		str = fmt.Sprintf("Expected *rpc.ValidationError but got %T with message `%s`", err, err.Error())
@@ -81,7 +83,7 @@ func ExpectInvalidTypeError(err error) string {
 	switch err.(type) {
 	case nil:
 		str = "Expected error but didn't get one"
-	case *InvalidTypeError:
+	case *shared.InvalidTypeError:
 		break
 	default:
 		str = fmt.Sprintf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error())
@@ -94,7 +96,7 @@ func ExpectInsufficientParamsError(err error) string {
 	switch err.(type) {
 	case nil:
 		str = "Expected error but didn't get one"
-	case *InsufficientParamsError:
+	case *shared.InsufficientParamsError:
 		break
 	default:
 		str = fmt.Sprintf("Expected *rpc.InsufficientParamsError but got %T with message %s", err, err.Error())
@@ -107,7 +109,7 @@ func ExpectDecodeParamError(err error) string {
 	switch err.(type) {
 	case nil:
 		str = "Expected error but didn't get one"
-	case *DecodeParamError:
+	case *shared.DecodeParamError:
 		break
 	default:
 		str = fmt.Sprintf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error())
diff --git a/rpc/api/db.go b/rpc/api/db.go
new file mode 100644
index 0000000000000000000000000000000000000000..6f10d64475c6cf9394a9ea3f507ff29536f18e94
--- /dev/null
+++ b/rpc/api/db.go
@@ -0,0 +1,128 @@
+package api
+
+import (
+	"github.com/ethereum/go-ethereum/eth"
+	"github.com/ethereum/go-ethereum/rpc/codec"
+	"github.com/ethereum/go-ethereum/rpc/shared"
+	"github.com/ethereum/go-ethereum/xeth"
+)
+
+const (
+	DbApiversion = "1.0"
+)
+
+var (
+	// mapping between methods and handlers
+	DbMapping = map[string]dbhandler{
+		"db_getString": (*dbApi).GetString,
+		"db_putString": (*dbApi).PutString,
+		"db_getHex":    (*dbApi).GetHex,
+		"db_putHex":    (*dbApi).PutHex,
+	}
+)
+
+// db callback handler
+type dbhandler func(*dbApi, *shared.Request) (interface{}, error)
+
+// db api provider
+type dbApi struct {
+	xeth     *xeth.XEth
+	ethereum *eth.Ethereum
+	methods  map[string]dbhandler
+	codec    codec.ApiCoder
+}
+
+// create a new db api instance
+func NewDbApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *dbApi {
+	return &dbApi{
+		xeth:     xeth,
+		ethereum: ethereum,
+		methods:  DbMapping,
+		codec:    coder.New(nil),
+	}
+}
+
+// collection with supported methods
+func (self *dbApi) Methods() []string {
+	methods := make([]string, len(self.methods))
+	i := 0
+	for k := range self.methods {
+		methods[i] = k
+		i++
+	}
+	return methods
+}
+
+// Execute given request
+func (self *dbApi) Execute(req *shared.Request) (interface{}, error) {
+	if callback, ok := self.methods[req.Method]; ok {
+		return callback(self, req)
+	}
+
+	return nil, &shared.NotImplementedError{req.Method}
+}
+
+func (self *dbApi) Name() string {
+	return shared.DbApiName
+}
+
+func (self *dbApi) ApiVersion() string {
+	return DbApiversion
+}
+
+func (self *dbApi) GetString(req *shared.Request) (interface{}, error) {
+	args := new(DbArgs)
+	if err := self.codec.Decode(req.Params, &args); err != nil {
+		return nil, shared.NewDecodeParamError(err.Error())
+	}
+
+	if err := args.requirements(); err != nil {
+		return nil, err
+	}
+
+	ret, err := self.xeth.DbGet([]byte(args.Database + args.Key))
+	return string(ret), err
+}
+
+func (self *dbApi) PutString(req *shared.Request) (interface{}, error) {
+	args := new(DbArgs)
+	if err := self.codec.Decode(req.Params, &args); err != nil {
+		return nil, shared.NewDecodeParamError(err.Error())
+	}
+
+	if err := args.requirements(); err != nil {
+		return nil, err
+	}
+
+	return self.xeth.DbPut([]byte(args.Database+args.Key), args.Value), nil
+}
+
+func (self *dbApi) GetHex(req *shared.Request) (interface{}, error) {
+	args := new(DbHexArgs)
+	if err := self.codec.Decode(req.Params, &args); err != nil {
+		return nil, shared.NewDecodeParamError(err.Error())
+	}
+
+	if err := args.requirements(); err != nil {
+		return nil, err
+	}
+
+	if res, err := self.xeth.DbGet([]byte(args.Database + args.Key)); err == nil {
+		return newHexData(res), nil
+	} else {
+		return nil, err
+	}
+}
+
+func (self *dbApi) PutHex(req *shared.Request) (interface{}, error) {
+	args := new(DbHexArgs)
+	if err := self.codec.Decode(req.Params, &args); err != nil {
+		return nil, shared.NewDecodeParamError(err.Error())
+	}
+
+	if err := args.requirements(); err != nil {
+		return nil, err
+	}
+
+	return self.xeth.DbPut([]byte(args.Database+args.Key), args.Value), nil
+}
diff --git a/rpc/api/db_args.go b/rpc/api/db_args.go
new file mode 100644
index 0000000000000000000000000000000000000000..459616d871cc64e056f967db70f5ad30af6cd594
--- /dev/null
+++ b/rpc/api/db_args.go
@@ -0,0 +1,110 @@
+package api
+
+import (
+	"encoding/json"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/rpc/shared"
+)
+
+type DbArgs struct {
+	Database string
+	Key      string
+	Value    []byte
+}
+
+func (args *DbArgs) UnmarshalJSON(b []byte) (err error) {
+	var obj []interface{}
+	if err := json.Unmarshal(b, &obj); err != nil {
+		return shared.NewDecodeParamError(err.Error())
+	}
+
+	if len(obj) < 2 {
+		return shared.NewInsufficientParamsError(len(obj), 2)
+	}
+
+	var objstr string
+	var ok bool
+
+	if objstr, ok = obj[0].(string); !ok {
+		return shared.NewInvalidTypeError("database", "not a string")
+	}
+	args.Database = objstr
+
+	if objstr, ok = obj[1].(string); !ok {
+		return shared.NewInvalidTypeError("key", "not a string")
+	}
+	args.Key = objstr
+
+	if len(obj) > 2 {
+		objstr, ok = obj[2].(string)
+		if !ok {
+			return shared.NewInvalidTypeError("value", "not a string")
+		}
+
+		args.Value = []byte(objstr)
+	}
+
+	return nil
+}
+
+func (a *DbArgs) requirements() error {
+	if len(a.Database) == 0 {
+		return shared.NewValidationError("Database", "cannot be blank")
+	}
+	if len(a.Key) == 0 {
+		return shared.NewValidationError("Key", "cannot be blank")
+	}
+	return nil
+}
+
+type DbHexArgs struct {
+	Database string
+	Key      string
+	Value    []byte
+}
+
+func (args *DbHexArgs) UnmarshalJSON(b []byte) (err error) {
+	var obj []interface{}
+	if err := json.Unmarshal(b, &obj); err != nil {
+		return shared.NewDecodeParamError(err.Error())
+	}
+
+	if len(obj) < 2 {
+		return shared.NewInsufficientParamsError(len(obj), 2)
+	}
+
+	var objstr string
+	var ok bool
+
+	if objstr, ok = obj[0].(string); !ok {
+		return shared.NewInvalidTypeError("database", "not a string")
+	}
+	args.Database = objstr
+
+	if objstr, ok = obj[1].(string); !ok {
+		return shared.NewInvalidTypeError("key", "not a string")
+	}
+	args.Key = objstr
+
+	if len(obj) > 2 {
+		objstr, ok = obj[2].(string)
+		if !ok {
+			return shared.NewInvalidTypeError("value", "not a string")
+		}
+
+		args.Value = common.FromHex(objstr)
+	}
+
+	return nil
+}
+
+func (a *DbHexArgs) requirements() error {
+	if len(a.Database) == 0 {
+		return shared.NewValidationError("Database", "cannot be blank")
+	}
+	if len(a.Key) == 0 {
+		return shared.NewValidationError("Key", "cannot be blank")
+	}
+	return nil
+}
diff --git a/rpc/api/db_js.go b/rpc/api/db_js.go
new file mode 100644
index 0000000000000000000000000000000000000000..62cdcd20eef4ed6538f9e321e8aa6d03a3a7f1fe
--- /dev/null
+++ b/rpc/api/db_js.go
@@ -0,0 +1,41 @@
+package api
+
+const Db_JS = `
+web3._extend({
+	property: 'db',
+	methods:
+	[
+		new web3._extend.Method({
+			name: 'getString',
+			call: 'db_getString',
+			params: 2,
+			inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString],
+			outputFormatter: web3._extend.formatters.formatOutputString
+		}),
+		new web3._extend.Method({
+			name: 'putString',
+			call: 'db_putString',
+			params: 3,
+			inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString],
+			outputFormatter: web3._extend.formatters.formatOutputBool
+		}),
+		new web3._extend.Method({
+			name: 'getHex',
+			call: 'db_getHex',
+			params: 2,
+			inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString],
+			outputFormatter: web3._extend.formatters.formatOutputString
+		}),
+		new web3._extend.Method({
+			name: 'putHex',
+			call: 'db_putHex',
+			params: 3,
+			inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString],
+			outputFormatter: web3._extend.formatters.formatOutputBool
+		}),
+	],
+	properties:
+	[
+	]
+});
+`
diff --git a/rpc/api/debug.go b/rpc/api/debug.go
index 5b6a449dcedc8e7727c34d554fd4ea2d519abbb8..b451d8662489aa7f6eaf00c80e3b08f5887d7462 100644
--- a/rpc/api/debug.go
+++ b/rpc/api/debug.go
@@ -71,7 +71,7 @@ func (self *debugApi) Execute(req *shared.Request) (interface{}, error) {
 }
 
 func (self *debugApi) Name() string {
-	return DebugApiName
+	return shared.DebugApiName
 }
 
 func (self *debugApi) ApiVersion() string {
diff --git a/rpc/api/eth.go b/rpc/api/eth.go
index cb678922babd4cf83f710638a1cd5dff194d532c..0dff138c65142b8964663f260821967a5eb894df 100644
--- a/rpc/api/eth.go
+++ b/rpc/api/eth.go
@@ -28,48 +28,49 @@ type ethhandler func(*ethApi, *shared.Request) (interface{}, error)
 
 var (
 	ethMapping = map[string]ethhandler{
-		"eth_accounts":                          (*ethApi).Accounts,
-		"eth_blockNumber":                       (*ethApi).BlockNumber,
-		"eth_getBalance":                        (*ethApi).GetBalance,
-		"eth_protocolVersion":                   (*ethApi).ProtocolVersion,
-		"eth_coinbase":                          (*ethApi).Coinbase,
-		"eth_mining":                            (*ethApi).IsMining,
-		"eth_gasPrice":                          (*ethApi).GasPrice,
-		"eth_getStorage":                        (*ethApi).GetStorage,
-		"eth_storageAt":                         (*ethApi).GetStorage,
-		"eth_getStorageAt":                      (*ethApi).GetStorageAt,
-		"eth_getTransactionCount":               (*ethApi).GetTransactionCount,
-		"eth_getBlockTransactionCountByHash":    (*ethApi).GetBlockTransactionCountByHash,
-		"eth_getBlockTransactionCountByNumber":  (*ethApi).GetBlockTransactionCountByNumber,
-		"eth_getUncleCountByBlockHash":          (*ethApi).GetUncleCountByBlockHash,
-		"eth_getUncleCountByBlockNumber":        (*ethApi).GetUncleCountByBlockNumber,
-		"eth_getData":                           (*ethApi).GetData,
-		"eth_getCode":                           (*ethApi).GetData,
-		"eth_sign":                              (*ethApi).Sign,
-		"eth_sendRawTransaction":                (*ethApi).PushTx,
-		"eth_sendTransaction":                   (*ethApi).SendTransaction,
-		"eth_transact":                          (*ethApi).SendTransaction,
-		"eth_estimateGas":                       (*ethApi).EstimateGas,
-		"eth_call":                              (*ethApi).Call,
-		"eth_flush":                             (*ethApi).Flush,
-		"eth_getBlockByHash":                    (*ethApi).GetBlockByHash,
-		"eth_getBlockByNumber":                  (*ethApi).GetBlockByNumber,
-		"eth_getTransactionByHash":              (*ethApi).GetTransactionByHash,
-		"eth_getTransactionByBlockHashAndIndex": (*ethApi).GetTransactionByBlockHashAndIndex,
-		"eth_getUncleByBlockHashAndIndex":       (*ethApi).GetUncleByBlockHashAndIndex,
-		"eth_getUncleByBlockNumberAndIndex":     (*ethApi).GetUncleByBlockNumberAndIndex,
-		"eth_getCompilers":                      (*ethApi).GetCompilers,
-		"eth_compileSolidity":                   (*ethApi).CompileSolidity,
-		"eth_newFilter":                         (*ethApi).NewFilter,
-		"eth_newBlockFilter":                    (*ethApi).NewBlockFilter,
-		"eth_newPendingTransactionFilter":       (*ethApi).NewPendingTransactionFilter,
-		"eth_uninstallFilter":                   (*ethApi).UninstallFilter,
-		"eth_getFilterChanges":                  (*ethApi).GetFilterChanges,
-		"eth_getFilterLogs":                     (*ethApi).GetFilterLogs,
-		"eth_getLogs":                           (*ethApi).GetLogs,
-		"eth_hashrate":                          (*ethApi).Hashrate,
-		"eth_getWork":                           (*ethApi).GetWork,
-		"eth_submitWork":                        (*ethApi).SubmitWork,
+		"eth_accounts":                            (*ethApi).Accounts,
+		"eth_blockNumber":                         (*ethApi).BlockNumber,
+		"eth_getBalance":                          (*ethApi).GetBalance,
+		"eth_protocolVersion":                     (*ethApi).ProtocolVersion,
+		"eth_coinbase":                            (*ethApi).Coinbase,
+		"eth_mining":                              (*ethApi).IsMining,
+		"eth_gasPrice":                            (*ethApi).GasPrice,
+		"eth_getStorage":                          (*ethApi).GetStorage,
+		"eth_storageAt":                           (*ethApi).GetStorage,
+		"eth_getStorageAt":                        (*ethApi).GetStorageAt,
+		"eth_getTransactionCount":                 (*ethApi).GetTransactionCount,
+		"eth_getBlockTransactionCountByHash":      (*ethApi).GetBlockTransactionCountByHash,
+		"eth_getBlockTransactionCountByNumber":    (*ethApi).GetBlockTransactionCountByNumber,
+		"eth_getUncleCountByBlockHash":            (*ethApi).GetUncleCountByBlockHash,
+		"eth_getUncleCountByBlockNumber":          (*ethApi).GetUncleCountByBlockNumber,
+		"eth_getData":                             (*ethApi).GetData,
+		"eth_getCode":                             (*ethApi).GetData,
+		"eth_sign":                                (*ethApi).Sign,
+		"eth_sendRawTransaction":                  (*ethApi).SendRawTransaction,
+		"eth_sendTransaction":                     (*ethApi).SendTransaction,
+		"eth_transact":                            (*ethApi).SendTransaction,
+		"eth_estimateGas":                         (*ethApi).EstimateGas,
+		"eth_call":                                (*ethApi).Call,
+		"eth_flush":                               (*ethApi).Flush,
+		"eth_getBlockByHash":                      (*ethApi).GetBlockByHash,
+		"eth_getBlockByNumber":                    (*ethApi).GetBlockByNumber,
+		"eth_getTransactionByHash":                (*ethApi).GetTransactionByHash,
+		"eth_getTransactionByBlockNumberAndIndex": (*ethApi).GetTransactionByBlockNumberAndIndex,
+		"eth_getTransactionByBlockHashAndIndex":   (*ethApi).GetTransactionByBlockHashAndIndex,
+		"eth_getUncleByBlockHashAndIndex":         (*ethApi).GetUncleByBlockHashAndIndex,
+		"eth_getUncleByBlockNumberAndIndex":       (*ethApi).GetUncleByBlockNumberAndIndex,
+		"eth_getCompilers":                        (*ethApi).GetCompilers,
+		"eth_compileSolidity":                     (*ethApi).CompileSolidity,
+		"eth_newFilter":                           (*ethApi).NewFilter,
+		"eth_newBlockFilter":                      (*ethApi).NewBlockFilter,
+		"eth_newPendingTransactionFilter":         (*ethApi).NewPendingTransactionFilter,
+		"eth_uninstallFilter":                     (*ethApi).UninstallFilter,
+		"eth_getFilterChanges":                    (*ethApi).GetFilterChanges,
+		"eth_getFilterLogs":                       (*ethApi).GetFilterLogs,
+		"eth_getLogs":                             (*ethApi).GetLogs,
+		"eth_hashrate":                            (*ethApi).Hashrate,
+		"eth_getWork":                             (*ethApi).GetWork,
+		"eth_submitWork":                          (*ethApi).SubmitWork,
 	}
 )
 
@@ -99,7 +100,7 @@ func (self *ethApi) Execute(req *shared.Request) (interface{}, error) {
 }
 
 func (self *ethApi) Name() string {
-	return EthApiName
+	return shared.EthApiName
 }
 
 func (self *ethApi) ApiVersion() string {
@@ -115,7 +116,8 @@ func (self *ethApi) Hashrate(req *shared.Request) (interface{}, error) {
 }
 
 func (self *ethApi) BlockNumber(req *shared.Request) (interface{}, error) {
-	return self.xeth.CurrentBlock().Number(), nil
+	num := self.xeth.CurrentBlock().Number()
+	return newHexNum(num.Bytes()), nil
 }
 
 func (self *ethApi) GetBalance(req *shared.Request) (interface{}, error) {
@@ -248,8 +250,7 @@ func (self *ethApi) Sign(req *shared.Request) (interface{}, error) {
 	return v, nil
 }
 
-
-func (self *ethApi) PushTx(req *shared.Request) (interface{}, error) {
+func (self *ethApi) SendRawTransaction(req *shared.Request) (interface{}, error) {
 	args := new(NewDataArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
diff --git a/rpc/api/eth_args.go b/rpc/api/eth_args.go
index 54eb7201dc5d636c05ac9dce5ec642d06185a514..bf8ffead6ca33973163b8995515610adf1c8db46 100644
--- a/rpc/api/eth_args.go
+++ b/rpc/api/eth_args.go
@@ -227,32 +227,32 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
 }
 
 type NewDataArgs struct {
-    Data string
+	Data string
 }
 
 func (args *NewDataArgs) UnmarshalJSON(b []byte) (err error) {
-    var obj []interface{}
+	var obj []interface{}
 
-    if err := json.Unmarshal(b, &obj); err != nil {
-        return shared.NewDecodeParamError(err.Error())
-    }
+	if err := json.Unmarshal(b, &obj); err != nil {
+		return shared.NewDecodeParamError(err.Error())
+	}
 
-    // Check for sufficient params
-    if len(obj) < 1 {
-        return shared.NewInsufficientParamsError(len(obj), 1)
-    }
+	// Check for sufficient params
+	if len(obj) < 1 {
+		return shared.NewInsufficientParamsError(len(obj), 1)
+	}
 
-    data, ok := obj[0].(string)
-    if !ok {
-        return shared.NewInvalidTypeError("data", "not a string")
-    }
-    args.Data = data
+	data, ok := obj[0].(string)
+	if !ok {
+		return shared.NewInvalidTypeError("data", "not a string")
+	}
+	args.Data = data
 
-    if len(args.Data) == 0 {
-        return shared.NewValidationError("data", "is required")
-    }
+	if len(args.Data) == 0 {
+		return shared.NewValidationError("data", "is required")
+	}
 
-    return nil
+	return nil
 }
 
 type NewSigArgs struct {
@@ -466,21 +466,21 @@ func (args *CallArgs) UnmarshalJSON(b []byte) (err error) {
 	}
 	args.Value = num
 
-	if ext.Gas == nil {
-		num = big.NewInt(0)
-	} else {
+	if ext.Gas != nil {
 		if num, err = numString(ext.Gas); err != nil {
 			return err
 		}
+	} else {
+		num = nil
 	}
 	args.Gas = num
 
-	if ext.GasPrice == nil {
-		num = big.NewInt(0)
-	} else {
+	if ext.GasPrice != nil {
 		if num, err = numString(ext.GasPrice); err != nil {
 			return err
 		}
+	} else {
+		num = nil
 	}
 	args.GasPrice = num
 
diff --git a/rpc/api/eth_js.go b/rpc/api/eth_js.go
index f7630bdd5d063a25582c074445a091cb96b8fbb6..e1268eb763f09670df210a9a9f2b9deb1283dd85 100644
--- a/rpc/api/eth_js.go
+++ b/rpc/api/eth_js.go
@@ -1,3 +1,20 @@
 package api
 
 // JS api provided by web3.js
+// eth_sign not standard
+
+const Eth_JS = `
+web3._extend({
+	property: 'eth',
+	methods:
+	[
+		new web3._extend.Method({
+			name: 'sign',
+			call: 'eth_sign',
+			params: 2,
+			inputFormatter: [web3._extend.formatters.formatInputString,web3._extend.formatters.formatInputString],
+			outputFormatter: web3._extend.formatters.formatOutputString
+		})
+	]
+});
+`
diff --git a/rpc/api/mergedapi.go b/rpc/api/mergedapi.go
index b62477a140a5e42dab5b17e71027b1217f9c4e10..bc4fa32e893896708be60050133e59d3f80e6979 100644
--- a/rpc/api/mergedapi.go
+++ b/rpc/api/mergedapi.go
@@ -1,6 +1,8 @@
 package api
 
 import (
+	"github.com/ethereum/go-ethereum/logger"
+	"github.com/ethereum/go-ethereum/logger/glog"
 	"github.com/ethereum/go-ethereum/rpc/shared"
 )
 
@@ -11,14 +13,14 @@ const (
 // combines multiple API's
 type MergedApi struct {
 	apis    map[string]string
-	methods map[string]EthereumApi
+	methods map[string]shared.EthereumApi
 }
 
 // create new merged api instance
-func newMergedApi(apis ...EthereumApi) *MergedApi {
+func newMergedApi(apis ...shared.EthereumApi) *MergedApi {
 	mergedApi := new(MergedApi)
 	mergedApi.apis = make(map[string]string, len(apis))
-	mergedApi.methods = make(map[string]EthereumApi)
+	mergedApi.methods = make(map[string]shared.EthereumApi)
 
 	for _, api := range apis {
 		mergedApi.apis[api.Name()] = api.ApiVersion()
@@ -40,6 +42,8 @@ func (self *MergedApi) Methods() []string {
 
 // Call the correct API's Execute method for the given request
 func (self *MergedApi) Execute(req *shared.Request) (interface{}, error) {
+	glog.V(logger.Detail).Infof("rpc method: %s", req.Method)
+
 	if res, _ := self.handle(req); res != nil {
 		return res, nil
 	}
@@ -50,7 +54,7 @@ func (self *MergedApi) Execute(req *shared.Request) (interface{}, error) {
 }
 
 func (self *MergedApi) Name() string {
-	return MergedApiName
+	return shared.MergedApiName
 }
 
 func (self *MergedApi) ApiVersion() string {
diff --git a/rpc/api/mergedapi_js.go b/rpc/api/mergedapi_js.go
deleted file mode 100644
index 778f64ec17cd4fd767e18d43231361d3aff70366..0000000000000000000000000000000000000000
--- a/rpc/api/mergedapi_js.go
+++ /dev/null
@@ -1 +0,0 @@
-package api
diff --git a/rpc/api/miner.go b/rpc/api/miner.go
index 0b5e74f528550fba97a118987b59c2524e6ac517..7a84cb9ae285d5600b0e550c89e84d32ab0e5b27 100644
--- a/rpc/api/miner.go
+++ b/rpc/api/miner.go
@@ -66,7 +66,7 @@ func (self *minerApi) Methods() []string {
 }
 
 func (self *minerApi) Name() string {
-	return MinerApiName
+	return shared.MinerApiName
 }
 
 func (self *minerApi) ApiVersion() string {
diff --git a/rpc/api/net.go b/rpc/api/net.go
index d6888ee4a29f89eaaf1aa401f225cbe35e6213ee..7616546610e42a0f162083f1d54fd326b6025221 100644
--- a/rpc/api/net.go
+++ b/rpc/api/net.go
@@ -63,7 +63,7 @@ func (self *netApi) Execute(req *shared.Request) (interface{}, error) {
 }
 
 func (self *netApi) Name() string {
-	return NetApiName
+	return shared.NetApiName
 }
 
 func (self *netApi) ApiVersion() string {
@@ -77,7 +77,7 @@ func (self *netApi) Version(req *shared.Request) (interface{}, error) {
 
 // Number of connected peers
 func (self *netApi) PeerCount(req *shared.Request) (interface{}, error) {
-	return self.xeth.PeerCount(), nil
+	return newHexNum(self.xeth.PeerCount()), nil
 }
 
 func (self *netApi) IsListening(req *shared.Request) (interface{}, error) {
diff --git a/rpc/api/personal.go b/rpc/api/personal.go
index 7a6c91c821bedce0037e91322fbf6b62fe7a5976..b4a63ea7a576e42ac3d8a3c0eee85e60fa364dd2 100644
--- a/rpc/api/personal.go
+++ b/rpc/api/personal.go
@@ -66,7 +66,7 @@ func (self *personalApi) Execute(req *shared.Request) (interface{}, error) {
 }
 
 func (self *personalApi) Name() string {
-	return PersonalApiName
+	return shared.PersonalApiName
 }
 
 func (self *personalApi) ApiVersion() string {
diff --git a/rpc/api/shh.go b/rpc/api/shh.go
index e83a7b22e06ec06ee0115e6a6ffc16d4d3cbd306..18a8fd15def996d68dead5cff3452afc634659f8 100644
--- a/rpc/api/shh.go
+++ b/rpc/api/shh.go
@@ -72,7 +72,7 @@ func (self *shhApi) Execute(req *shared.Request) (interface{}, error) {
 }
 
 func (self *shhApi) Name() string {
-	return ShhApiName
+	return shared.ShhApiName
 }
 
 func (self *shhApi) ApiVersion() string {
diff --git a/rpc/api/txpool.go b/rpc/api/txpool.go
index 64550bdafb4beb430bf6e8ccb42ac9ede28df2f4..25ad6e9b2deb9d4e19f2d80364ff4a5ee693c74b 100644
--- a/rpc/api/txpool.go
+++ b/rpc/api/txpool.go
@@ -60,7 +60,7 @@ func (self *txPoolApi) Execute(req *shared.Request) (interface{}, error) {
 }
 
 func (self *txPoolApi) Name() string {
-	return TxPoolApiName
+	return shared.TxPoolApiName
 }
 
 func (self *txPoolApi) ApiVersion() string {
diff --git a/rpc/api/utils.go b/rpc/api/utils.go
index 40bcae52f9b554d894ffee49c9ec67c2c65b1267..6e4835de61db1889fcf76b7c59903d3ed5648e1b 100644
--- a/rpc/api/utils.go
+++ b/rpc/api/utils.go
@@ -7,6 +7,7 @@ import (
 
 	"github.com/ethereum/go-ethereum/eth"
 	"github.com/ethereum/go-ethereum/rpc/codec"
+	"github.com/ethereum/go-ethereum/rpc/shared"
 	"github.com/ethereum/go-ethereum/xeth"
 )
 
@@ -23,6 +24,14 @@ var (
 			"chainSyncStatus",
 			"setSolc",
 			"datadir",
+			"startRPC",
+			"stopRPC",
+		},
+		"db": []string{
+			"getString",
+			"putString",
+			"getHex",
+			"putHex",
 		},
 		"debug": []string{
 			"dumpBlock",
@@ -123,33 +132,35 @@ var (
 )
 
 // Parse a comma separated API string to individual api's
-func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.Ethereum) ([]EthereumApi, error) {
+func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.Ethereum) ([]shared.EthereumApi, error) {
 	if len(strings.TrimSpace(apistr)) == 0 {
 		return nil, fmt.Errorf("Empty apistr provided")
 	}
 
 	names := strings.Split(apistr, ",")
-	apis := make([]EthereumApi, len(names))
+	apis := make([]shared.EthereumApi, len(names))
 
 	for i, name := range names {
 		switch strings.ToLower(strings.TrimSpace(name)) {
-		case AdminApiName:
+		case shared.AdminApiName:
 			apis[i] = NewAdminApi(xeth, eth, codec)
-		case DebugApiName:
+		case shared.DebugApiName:
 			apis[i] = NewDebugApi(xeth, eth, codec)
-		case EthApiName:
+		case shared.DbApiName:
+			apis[i] = NewDbApi(xeth, eth, codec)
+		case shared.EthApiName:
 			apis[i] = NewEthApi(xeth, codec)
-		case MinerApiName:
+		case shared.MinerApiName:
 			apis[i] = NewMinerApi(eth, codec)
-		case NetApiName:
+		case shared.NetApiName:
 			apis[i] = NewNetApi(xeth, eth, codec)
-		case ShhApiName:
+		case shared.ShhApiName:
 			apis[i] = NewShhApi(xeth, eth, codec)
-		case TxPoolApiName:
+		case shared.TxPoolApiName:
 			apis[i] = NewTxPoolApi(xeth, eth, codec)
-		case PersonalApiName:
+		case shared.PersonalApiName:
 			apis[i] = NewPersonalApi(xeth, eth, codec)
-		case Web3ApiName:
+		case shared.Web3ApiName:
 			apis[i] = NewWeb3Api(xeth, codec)
 		default:
 			return nil, fmt.Errorf("Unknown API '%s'", name)
@@ -161,19 +172,23 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.
 
 func Javascript(name string) string {
 	switch strings.ToLower(strings.TrimSpace(name)) {
-	case AdminApiName:
+	case shared.AdminApiName:
 		return Admin_JS
-	case DebugApiName:
+	case shared.DebugApiName:
 		return Debug_JS
-	case MinerApiName:
+	case shared.DbApiName:
+		return Db_JS
+	case shared.EthApiName:
+		return Eth_JS
+	case shared.MinerApiName:
 		return Miner_JS
-	case NetApiName:
+	case shared.NetApiName:
 		return Net_JS
-	case ShhApiName:
+	case shared.ShhApiName:
 		return Shh_JS
-	case TxPoolApiName:
+	case shared.TxPoolApiName:
 		return TxPool_JS
-	case PersonalApiName:
+	case shared.PersonalApiName:
 		return Personal_JS
 	}
 
diff --git a/rpc/api/web3.go b/rpc/api/web3.go
index ed5008446d6b115c1740546c7ccbd74603b1ede3..4c20baa25943137cf430f37737c2308ba3a0fdc6 100644
--- a/rpc/api/web3.go
+++ b/rpc/api/web3.go
@@ -60,7 +60,7 @@ func (self *web3Api) Execute(req *shared.Request) (interface{}, error) {
 }
 
 func (self *web3Api) Name() string {
-	return Web3ApiName
+	return shared.Web3ApiName
 }
 
 func (self *web3Api) ApiVersion() string {
diff --git a/rpc/api/web3_args.go b/rpc/api/web3_args.go
index 5455a6c8e55cfdd8000a0ac6fe7e78d234380e60..38af7191e382f750a2a6f88bc93ae449f6e2cfc6 100644
--- a/rpc/api/web3_args.go
+++ b/rpc/api/web3_args.go
@@ -1,5 +1,29 @@
 package api
 
+import (
+	"encoding/json"
+
+	"github.com/ethereum/go-ethereum/rpc/shared"
+)
+
 type Sha3Args struct {
 	Data string
 }
+
+func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) {
+	var obj []interface{}
+	if err := json.Unmarshal(b, &obj); err != nil {
+		return shared.NewDecodeParamError(err.Error())
+	}
+
+	if len(obj) < 1 {
+		return shared.NewInsufficientParamsError(len(obj), 1)
+	}
+
+	argstr, ok := obj[0].(string)
+	if !ok {
+		return shared.NewInvalidTypeError("data", "is not a string")
+	}
+	args.Data = argstr
+	return nil
+}
diff --git a/rpc/api_test.go b/rpc/api_test.go
deleted file mode 100644
index c3546e98f4f5836a181a90f0bf13218159872fe0..0000000000000000000000000000000000000000
--- a/rpc/api_test.go
+++ /dev/null
@@ -1,205 +0,0 @@
-package rpc
-
-import (
-	"encoding/json"
-	"strconv"
-	"testing"
-
-	"github.com/ethereum/go-ethereum/common/compiler"
-	"github.com/ethereum/go-ethereum/eth"
-	"github.com/ethereum/go-ethereum/xeth"
-)
-
-func TestWeb3Sha3(t *testing.T) {
-	jsonstr := `{"jsonrpc":"2.0","method":"web3_sha3","params":["0x68656c6c6f20776f726c64"],"id":64}`
-	expected := "0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad"
-
-	api := &EthereumApi{}
-
-	var req RpcRequest
-	json.Unmarshal([]byte(jsonstr), &req)
-
-	var response interface{}
-	_ = api.GetRequestReply(&req, &response)
-
-	if response.(string) != expected {
-		t.Errorf("Expected %s got %s", expected, response)
-	}
-}
-
-const solcVersion = "0.9.23"
-
-func TestCompileSolidity(t *testing.T) {
-
-	solc, err := compiler.New("")
-	if solc == nil {
-		t.Skip("no solc found: skip")
-	} else if solc.Version() != solcVersion {
-		t.Skip("WARNING: skipping test because of solc different version (%v, test written for %v, may need to update)", solc.Version(), solcVersion)
-	}
-	source := `contract test {\n` +
-		"   /// @notice Will multiply `a` by 7." + `\n` +
-		`   function multiply(uint a) returns(uint d) {\n` +
-		`       return a * 7;\n` +
-		`   }\n` +
-		`}\n`
-
-	jsonstr := `{"jsonrpc":"2.0","method":"eth_compileSolidity","params":["` + source + `"],"id":64}`
-
-	expCode := "0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056"
-	expAbiDefinition := `[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]`
-	expUserDoc := `{"methods":{"multiply(uint256)":{"notice":"Will multiply ` + "`a`" + ` by 7."}}}`
-	expDeveloperDoc := `{"methods":{}}`
-	expCompilerVersion := solc.Version()
-	expLanguage := "Solidity"
-	expLanguageVersion := "0"
-	expSource := source
-
-	api := NewEthereumApi(xeth.NewTest(&eth.Ethereum{}, nil))
-
-	var req RpcRequest
-	json.Unmarshal([]byte(jsonstr), &req)
-
-	var response interface{}
-	err = api.GetRequestReply(&req, &response)
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-	respjson, err := json.Marshal(response)
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-
-	var contracts = make(map[string]*compiler.Contract)
-	err = json.Unmarshal(respjson, &contracts)
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-
-	if len(contracts) != 1 {
-		t.Errorf("expected one contract, got %v", len(contracts))
-	}
-
-	contract := contracts["test"]
-
-	if contract.Code != expCode {
-		t.Errorf("Expected \n%s got \n%s", expCode, contract.Code)
-	}
-
-	if strconv.Quote(contract.Info.Source) != `"`+expSource+`"` {
-		t.Errorf("Expected \n'%s' got \n'%s'", expSource, strconv.Quote(contract.Info.Source))
-	}
-
-	if contract.Info.Language != expLanguage {
-		t.Errorf("Expected %s got %s", expLanguage, contract.Info.Language)
-	}
-
-	if contract.Info.LanguageVersion != expLanguageVersion {
-		t.Errorf("Expected %s got %s", expLanguageVersion, contract.Info.LanguageVersion)
-	}
-
-	if contract.Info.CompilerVersion != expCompilerVersion {
-		t.Errorf("Expected %s got %s", expCompilerVersion, contract.Info.CompilerVersion)
-	}
-
-	userdoc, err := json.Marshal(contract.Info.UserDoc)
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-
-	devdoc, err := json.Marshal(contract.Info.DeveloperDoc)
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-
-	abidef, err := json.Marshal(contract.Info.AbiDefinition)
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-
-	if string(abidef) != expAbiDefinition {
-		t.Errorf("Expected \n'%s' got \n'%s'", expAbiDefinition, string(abidef))
-	}
-
-	if string(userdoc) != expUserDoc {
-		t.Errorf("Expected \n'%s' got \n'%s'", expUserDoc, string(userdoc))
-	}
-
-	if string(devdoc) != expDeveloperDoc {
-		t.Errorf("Expected %s got %s", expDeveloperDoc, string(devdoc))
-	}
-}
-
-// func TestDbStr(t *testing.T) {
-// 	jsonput := `{"jsonrpc":"2.0","method":"db_putString","params":["testDB","myKey","myString"],"id":64}`
-// 	jsonget := `{"jsonrpc":"2.0","method":"db_getString","params":["testDB","myKey"],"id":64}`
-// 	expected := "myString"
-
-// 	xeth := &xeth.XEth{}
-// 	api := NewEthereumApi(xeth)
-// 	var response interface{}
-
-// 	var req RpcRequest
-// 	json.Unmarshal([]byte(jsonput), &req)
-// 	_ = api.GetRequestReply(&req, &response)
-
-// 	json.Unmarshal([]byte(jsonget), &req)
-// 	_ = api.GetRequestReply(&req, &response)
-
-// 	if response.(string) != expected {
-// 		t.Errorf("Expected %s got %s", expected, response)
-// 	}
-// }
-
-// func TestDbHexStr(t *testing.T) {
-// 	jsonput := `{"jsonrpc":"2.0","method":"db_putHex","params":["testDB","beefKey","0xbeef"],"id":64}`
-// 	jsonget := `{"jsonrpc":"2.0","method":"db_getHex","params":["testDB","beefKey"],"id":64}`
-// 	expected := "0xbeef"
-
-// 	xeth := &xeth.XEth{}
-// 	api := NewEthereumApi(xeth)
-// 	defer api.db.Close()
-// 	var response interface{}
-
-// 	var req RpcRequest
-// 	json.Unmarshal([]byte(jsonput), &req)
-// 	_ = api.GetRequestReply(&req, &response)
-
-// 	json.Unmarshal([]byte(jsonget), &req)
-// 	_ = api.GetRequestReply(&req, &response)
-
-// 	if response.(string) != expected {
-// 		t.Errorf("Expected %s got %s", expected, response)
-// 	}
-// }
-
-// func TestFilterClose(t *testing.T) {
-// 	t.Skip()
-// 	api := &EthereumApi{
-// 		logs:     make(map[int]*logFilter),
-// 		messages: make(map[int]*whisperFilter),
-// 		quit:     make(chan struct{}),
-// 	}
-
-// 	filterTickerTime = 1
-// 	api.logs[0] = &logFilter{}
-// 	api.messages[0] = &whisperFilter{}
-// 	var wg sync.WaitGroup
-// 	wg.Add(1)
-// 	go api.start()
-// 	go func() {
-// 		select {
-// 		case <-time.After(500 * time.Millisecond):
-// 			api.stop()
-// 			wg.Done()
-// 		}
-// 	}()
-// 	wg.Wait()
-// 	if len(api.logs) != 0 {
-// 		t.Error("expected logs to be empty")
-// 	}
-
-// 	if len(api.messages) != 0 {
-// 		t.Error("expected messages to be empty")
-// 	}
-// }
diff --git a/rpc/args.go b/rpc/args.go
deleted file mode 100644
index aa7d205498bc82279ac223f3b9880ee68b589c6a..0000000000000000000000000000000000000000
--- a/rpc/args.go
+++ /dev/null
@@ -1,1230 +0,0 @@
-package rpc
-
-import (
-	"encoding/json"
-	"fmt"
-	"math/big"
-
-	"github.com/ethereum/go-ethereum/common"
-)
-
-const (
-	defaultLogLimit  = 100
-	defaultLogOffset = 0
-)
-
-func blockHeightFromJson(msg json.RawMessage, number *int64) error {
-	var raw interface{}
-	if err := json.Unmarshal(msg, &raw); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-	return blockHeight(raw, number)
-}
-
-func blockHeight(raw interface{}, number *int64) error {
-	// Parse as integer
-	num, ok := raw.(float64)
-	if ok {
-		*number = int64(num)
-		return nil
-	}
-
-	// Parse as string/hexstring
-	str, ok := raw.(string)
-	if !ok {
-		return NewInvalidTypeError("", "not a number or string")
-	}
-
-	switch str {
-	case "earliest":
-		*number = 0
-	case "latest":
-		*number = -1
-	case "pending":
-		*number = -2
-	default:
-		if common.HasHexPrefix(str) {
-			*number = common.String2Big(str).Int64()
-		} else {
-			return NewInvalidTypeError("blockNumber", "is not a valid string")
-		}
-	}
-
-	return nil
-}
-
-func numString(raw interface{}) (*big.Int, error) {
-	var number *big.Int
-	// Parse as integer
-	num, ok := raw.(float64)
-	if ok {
-		number = big.NewInt(int64(num))
-		return number, nil
-	}
-
-	// Parse as string/hexstring
-	str, ok := raw.(string)
-	if ok {
-		number = common.String2Big(str)
-		return number, nil
-	}
-
-	return nil, NewInvalidTypeError("", "not a number or string")
-}
-
-// func toNumber(v interface{}) (int64, error) {
-// 	var str string
-// 	if v != nil {
-// 		var ok bool
-// 		str, ok = v.(string)
-// 		if !ok {
-// 			return 0, errors.New("is not a string or undefined")
-// 		}
-// 	} else {
-// 		str = "latest"
-// 	}
-
-// 	switch str {
-// 	case "latest":
-// 		return -1, nil
-// 	default:
-// 		return int64(common.Big(v.(string)).Int64()), nil
-// 	}
-// }
-
-// func hashString(raw interface{}, hash *string) error {
-// 	argstr, ok := raw.(string)
-// 	if !ok {
-// 		return NewInvalidTypeError("", "not a string")
-// 	}
-// 	v := common.IsHex(argstr)
-// 	hash = &argstr
-
-// 	return nil
-// }
-
-type GetBlockByHashArgs struct {
-	BlockHash  string
-	IncludeTxs bool
-}
-
-func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 2 {
-		return NewInsufficientParamsError(len(obj), 2)
-	}
-
-	argstr, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("blockHash", "not a string")
-	}
-	args.BlockHash = argstr
-
-	args.IncludeTxs = obj[1].(bool)
-
-	return nil
-}
-
-type GetBlockByNumberArgs struct {
-	BlockNumber int64
-	IncludeTxs  bool
-}
-
-func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 2 {
-		return NewInsufficientParamsError(len(obj), 2)
-	}
-
-	if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
-		return err
-	}
-
-	args.IncludeTxs = obj[1].(bool)
-
-	return nil
-}
-
-type NewDataArgs struct {
-    Data string
-}
-
-func (args *NewDataArgs) UnmarshalJSON(b []byte) (err error) {
-    var obj []interface{}
-
-    if err := json.Unmarshal(b, &obj); err != nil {
-        return NewDecodeParamError(err.Error())
-    }
-
-    // Check for sufficient params
-    if len(obj) < 1 {
-        return NewInsufficientParamsError(len(obj), 1)
-    }
-
-    data, ok := obj[0].(string)
-    if !ok {
-        return NewInvalidTypeError("data", "not a string")
-    }
-    args.Data = data
-
-    if len(args.Data) == 0 {
-        return NewValidationError("data", "is required")
-    }
-
-    return nil
-}
-
-type NewTxArgs struct {
-	From     string
-	To       string
-	Nonce    *big.Int
-	Value    *big.Int
-	Gas      *big.Int
-	GasPrice *big.Int
-	Data     string
-
-	BlockNumber int64
-}
-
-type NewSigArgs struct {
-	From string
-	Data string
-}
-
-func (args *NewSigArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	// Check for sufficient params
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	from, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("from", "not a string")
-	}
-	args.From = from
-
-	if len(args.From) == 0 {
-		return NewValidationError("from", "is required")
-	}
-
-	data, ok := obj[1].(string)
-	if !ok {
-		return NewInvalidTypeError("data", "not a string")
-	}
-	args.Data = data
-
-	if len(args.Data) == 0 {
-		return NewValidationError("data", "is required")
-	}
-
-	return nil
-}
-
-func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []json.RawMessage
-	var ext struct {
-		From     string
-		To       string
-		Nonce    interface{}
-		Value    interface{}
-		Gas      interface{}
-		GasPrice interface{}
-		Data     string
-	}
-
-	// Decode byte slice to array of RawMessages
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	// Check for sufficient params
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	// Decode 0th RawMessage to temporary struct
-	if err := json.Unmarshal(obj[0], &ext); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(ext.From) == 0 {
-		return NewValidationError("from", "is required")
-	}
-
-	args.From = ext.From
-	args.To = ext.To
-	args.Data = ext.Data
-
-	var num *big.Int
-	if ext.Nonce != nil {
-		num, err = numString(ext.Nonce)
-		if err != nil {
-			return err
-		}
-	}
-	args.Nonce = num
-
-	if ext.Value == nil {
-		num = big.NewInt(0)
-	} else {
-		num, err = numString(ext.Value)
-		if err != nil {
-			return err
-		}
-	}
-	args.Value = num
-
-	num = nil
-	if ext.Gas != nil {
-		if num, err = numString(ext.Gas); err != nil {
-			return err
-		}
-	} else {
-		num = nil
-	}
-	args.Gas = num
-
-	num = nil
-	if ext.GasPrice != nil {
-		if num, err = numString(ext.GasPrice); err != nil {
-			return err
-		}
-	} else {
-		num = nil
-	}
-	args.GasPrice = num
-
-	// Check for optional BlockNumber param
-	if len(obj) > 1 {
-		if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
-			return err
-		}
-	} else {
-		args.BlockNumber = -1
-	}
-
-	return nil
-}
-
-type CallArgs struct {
-	From     string
-	To       string
-	Value    *big.Int
-	Gas      *big.Int
-	GasPrice *big.Int
-	Data     string
-
-	BlockNumber int64
-}
-
-func (args *CallArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []json.RawMessage
-	var ext struct {
-		From     string
-		To       string
-		Value    interface{}
-		Gas      interface{}
-		GasPrice interface{}
-		Data     string
-	}
-
-	// Decode byte slice to array of RawMessages
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	// Check for sufficient params
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	// Decode 0th RawMessage to temporary struct
-	if err := json.Unmarshal(obj[0], &ext); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	args.From = ext.From
-
-	if len(ext.To) == 0 {
-		return NewValidationError("to", "is required")
-	}
-	args.To = ext.To
-
-	var num *big.Int
-	if ext.Value == nil {
-		num = big.NewInt(0)
-	} else {
-		if num, err = numString(ext.Value); err != nil {
-			return err
-		}
-	}
-	args.Value = num
-
-	if ext.Gas != nil {
-		if num, err = numString(ext.Gas); err != nil {
-			return err
-		}
-	} else {
-		num = nil
-	}
-	args.Gas = num
-
-	if ext.GasPrice != nil {
-		if num, err = numString(ext.GasPrice); err != nil {
-			return err
-		}
-	} else {
-		num = nil
-	}
-	args.GasPrice = num
-
-	args.Data = ext.Data
-
-	// Check for optional BlockNumber param
-	if len(obj) > 1 {
-		if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
-			return err
-		}
-	} else {
-		args.BlockNumber = -1
-	}
-
-	return nil
-}
-
-type GetStorageArgs struct {
-	Address     string
-	BlockNumber int64
-}
-
-func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	addstr, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("address", "not a string")
-	}
-	args.Address = addstr
-
-	if len(obj) > 1 {
-		if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
-			return err
-		}
-	} else {
-		args.BlockNumber = -1
-	}
-
-	return nil
-}
-
-type GetStorageAtArgs struct {
-	Address     string
-	Key         string
-	BlockNumber int64
-}
-
-func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 2 {
-		return NewInsufficientParamsError(len(obj), 2)
-	}
-
-	addstr, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("address", "not a string")
-	}
-	args.Address = addstr
-
-	keystr, ok := obj[1].(string)
-	if !ok {
-		return NewInvalidTypeError("key", "not a string")
-	}
-	args.Key = keystr
-
-	if len(obj) > 2 {
-		if err := blockHeight(obj[2], &args.BlockNumber); err != nil {
-			return err
-		}
-	} else {
-		args.BlockNumber = -1
-	}
-
-	return nil
-}
-
-type GetTxCountArgs struct {
-	Address     string
-	BlockNumber int64
-}
-
-func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	addstr, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("address", "not a string")
-	}
-	args.Address = addstr
-
-	if len(obj) > 1 {
-		if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
-			return err
-		}
-	} else {
-		args.BlockNumber = -1
-	}
-
-	return nil
-}
-
-type GetBalanceArgs struct {
-	Address     string
-	BlockNumber int64
-}
-
-func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	addstr, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("address", "not a string")
-	}
-	args.Address = addstr
-
-	if len(obj) > 1 {
-		if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
-			return err
-		}
-	} else {
-		args.BlockNumber = -1
-	}
-
-	return nil
-}
-
-type GetDataArgs struct {
-	Address     string
-	BlockNumber int64
-}
-
-func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	addstr, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("address", "not a string")
-	}
-	args.Address = addstr
-
-	if len(obj) > 1 {
-		if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
-			return err
-		}
-	} else {
-		args.BlockNumber = -1
-	}
-
-	return nil
-}
-
-type BlockNumArg struct {
-	BlockNumber int64
-}
-
-func (args *BlockNumArg) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-type BlockNumIndexArgs struct {
-	BlockNumber int64
-	Index       int64
-}
-
-func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 2 {
-		return NewInsufficientParamsError(len(obj), 2)
-	}
-
-	if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
-		return err
-	}
-
-	var arg1 *big.Int
-	if arg1, err = numString(obj[1]); err != nil {
-		return err
-	}
-	args.Index = arg1.Int64()
-
-	return nil
-}
-
-type HashArgs struct {
-	Hash string
-}
-
-func (args *HashArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	arg0, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("hash", "not a string")
-	}
-	args.Hash = arg0
-
-	return nil
-}
-
-type HashIndexArgs struct {
-	Hash  string
-	Index int64
-}
-
-func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 2 {
-		return NewInsufficientParamsError(len(obj), 2)
-	}
-
-	arg0, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("hash", "not a string")
-	}
-	args.Hash = arg0
-
-	arg1, ok := obj[1].(string)
-	if !ok {
-		return NewInvalidTypeError("index", "not a string")
-	}
-	args.Index = common.Big(arg1).Int64()
-
-	return nil
-}
-
-type Sha3Args struct {
-	Data string
-}
-
-func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	argstr, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("data", "is not a string")
-	}
-	args.Data = argstr
-	return nil
-}
-
-type BlockFilterArgs struct {
-	Earliest int64
-	Latest   int64
-	Address  []string
-	Topics   [][]string
-	Skip     int
-	Max      int
-}
-
-func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []struct {
-		FromBlock interface{} `json:"fromBlock"`
-		ToBlock   interface{} `json:"toBlock"`
-		Limit     interface{} `json:"limit"`
-		Offset    interface{} `json:"offset"`
-		Address   interface{} `json:"address"`
-		Topics    interface{} `json:"topics"`
-	}
-
-	if err = json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	// args.Earliest, err = toNumber(obj[0].ToBlock)
-	// if err != nil {
-	// 	return NewDecodeParamError(fmt.Sprintf("FromBlock %v", err))
-	// }
-	// args.Latest, err = toNumber(obj[0].FromBlock)
-	// if err != nil {
-	// 	return NewDecodeParamError(fmt.Sprintf("ToBlock %v", err))
-
-	var num int64
-	var numBig *big.Int
-
-	// if blank then latest
-	if obj[0].FromBlock == nil {
-		num = -1
-	} else {
-		if err := blockHeight(obj[0].FromBlock, &num); err != nil {
-			return err
-		}
-	}
-	// if -2 or other "silly" number, use latest
-	if num < 0 {
-		args.Earliest = -1 //latest block
-	} else {
-		args.Earliest = num
-	}
-
-	// if blank than latest
-	if obj[0].ToBlock == nil {
-		num = -1
-	} else {
-		if err := blockHeight(obj[0].ToBlock, &num); err != nil {
-			return err
-		}
-	}
-	args.Latest = num
-
-	if obj[0].Limit == nil {
-		numBig = big.NewInt(defaultLogLimit)
-	} else {
-		if numBig, err = numString(obj[0].Limit); err != nil {
-			return err
-		}
-	}
-	args.Max = int(numBig.Int64())
-
-	if obj[0].Offset == nil {
-		numBig = big.NewInt(defaultLogOffset)
-	} else {
-		if numBig, err = numString(obj[0].Offset); err != nil {
-			return err
-		}
-	}
-	args.Skip = int(numBig.Int64())
-
-	if obj[0].Address != nil {
-		marg, ok := obj[0].Address.([]interface{})
-		if ok {
-			v := make([]string, len(marg))
-			for i, arg := range marg {
-				argstr, ok := arg.(string)
-				if !ok {
-					return NewInvalidTypeError(fmt.Sprintf("address[%d]", i), "is not a string")
-				}
-				v[i] = argstr
-			}
-			args.Address = v
-		} else {
-			argstr, ok := obj[0].Address.(string)
-			if ok {
-				v := make([]string, 1)
-				v[0] = argstr
-				args.Address = v
-			} else {
-				return NewInvalidTypeError("address", "is not a string or array")
-			}
-		}
-	}
-
-	if obj[0].Topics != nil {
-		other, ok := obj[0].Topics.([]interface{})
-		if ok {
-			topicdbl := make([][]string, len(other))
-			for i, iv := range other {
-				if argstr, ok := iv.(string); ok {
-					// Found a string, push into first element of array
-					topicsgl := make([]string, 1)
-					topicsgl[0] = argstr
-					topicdbl[i] = topicsgl
-				} else if argarray, ok := iv.([]interface{}); ok {
-					// Found an array of other
-					topicdbl[i] = make([]string, len(argarray))
-					for j, jv := range argarray {
-						if v, ok := jv.(string); ok {
-							topicdbl[i][j] = v
-						} else if jv == nil {
-							topicdbl[i][j] = ""
-						} else {
-							return NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", i, j), "is not a string")
-						}
-					}
-				} else if iv == nil {
-					topicdbl[i] = []string{""}
-				} else {
-					return NewInvalidTypeError(fmt.Sprintf("topic[%d]", i), "not a string or array")
-				}
-			}
-			args.Topics = topicdbl
-			return nil
-		} else {
-			return NewInvalidTypeError("topic", "is not a string or array")
-		}
-	}
-
-	return nil
-}
-
-type DbArgs struct {
-	Database string
-	Key      string
-	Value    []byte
-}
-
-func (args *DbArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 2 {
-		return NewInsufficientParamsError(len(obj), 2)
-	}
-
-	var objstr string
-	var ok bool
-
-	if objstr, ok = obj[0].(string); !ok {
-		return NewInvalidTypeError("database", "not a string")
-	}
-	args.Database = objstr
-
-	if objstr, ok = obj[1].(string); !ok {
-		return NewInvalidTypeError("key", "not a string")
-	}
-	args.Key = objstr
-
-	if len(obj) > 2 {
-		objstr, ok = obj[2].(string)
-		if !ok {
-			return NewInvalidTypeError("value", "not a string")
-		}
-
-		args.Value = []byte(objstr)
-	}
-
-	return nil
-}
-
-func (a *DbArgs) requirements() error {
-	if len(a.Database) == 0 {
-		return NewValidationError("Database", "cannot be blank")
-	}
-	if len(a.Key) == 0 {
-		return NewValidationError("Key", "cannot be blank")
-	}
-	return nil
-}
-
-type DbHexArgs struct {
-	Database string
-	Key      string
-	Value    []byte
-}
-
-func (args *DbHexArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 2 {
-		return NewInsufficientParamsError(len(obj), 2)
-	}
-
-	var objstr string
-	var ok bool
-
-	if objstr, ok = obj[0].(string); !ok {
-		return NewInvalidTypeError("database", "not a string")
-	}
-	args.Database = objstr
-
-	if objstr, ok = obj[1].(string); !ok {
-		return NewInvalidTypeError("key", "not a string")
-	}
-	args.Key = objstr
-
-	if len(obj) > 2 {
-		objstr, ok = obj[2].(string)
-		if !ok {
-			return NewInvalidTypeError("value", "not a string")
-		}
-
-		args.Value = common.FromHex(objstr)
-	}
-
-	return nil
-}
-
-func (a *DbHexArgs) requirements() error {
-	if len(a.Database) == 0 {
-		return NewValidationError("Database", "cannot be blank")
-	}
-	if len(a.Key) == 0 {
-		return NewValidationError("Key", "cannot be blank")
-	}
-	return nil
-}
-
-type WhisperMessageArgs struct {
-	Payload  string
-	To       string
-	From     string
-	Topics   []string
-	Priority uint32
-	Ttl      uint32
-}
-
-func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []struct {
-		Payload  string
-		To       string
-		From     string
-		Topics   []string
-		Priority interface{}
-		Ttl      interface{}
-	}
-
-	if err = json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-	args.Payload = obj[0].Payload
-	args.To = obj[0].To
-	args.From = obj[0].From
-	args.Topics = obj[0].Topics
-
-	var num *big.Int
-	if num, err = numString(obj[0].Priority); err != nil {
-		return err
-	}
-	args.Priority = uint32(num.Int64())
-
-	if num, err = numString(obj[0].Ttl); err != nil {
-		return err
-	}
-	args.Ttl = uint32(num.Int64())
-
-	return nil
-}
-
-type CompileArgs struct {
-	Source string
-}
-
-func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-	argstr, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("arg0", "is not a string")
-	}
-	args.Source = argstr
-
-	return nil
-}
-
-type FilterStringArgs struct {
-	Word string
-}
-
-func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	var argstr string
-	argstr, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("filter", "not a string")
-	}
-	switch argstr {
-	case "latest", "pending":
-		break
-	default:
-		return NewValidationError("Word", "Must be `latest` or `pending`")
-	}
-	args.Word = argstr
-	return nil
-}
-
-type FilterIdArgs struct {
-	Id int
-}
-
-func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	var num *big.Int
-	if num, err = numString(obj[0]); err != nil {
-		return err
-	}
-	args.Id = int(num.Int64())
-
-	return nil
-}
-
-type WhisperIdentityArgs struct {
-	Identity string
-}
-
-func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	argstr, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("arg0", "not a string")
-	}
-	// if !common.IsHex(argstr) {
-	// 	return NewValidationError("arg0", "not a hexstring")
-	// }
-	args.Identity = argstr
-
-	return nil
-}
-
-type WhisperFilterArgs struct {
-	To     string
-	From   string
-	Topics [][]string
-}
-
-// UnmarshalJSON implements the json.Unmarshaler interface, invoked to convert a
-// JSON message blob into a WhisperFilterArgs structure.
-func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
-	// Unmarshal the JSON message and sanity check
-	var obj []struct {
-		To     interface{} `json:"to"`
-		From   interface{} `json:"from"`
-		Topics interface{} `json:"topics"`
-	}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-	// Retrieve the simple data contents of the filter arguments
-	if obj[0].To == nil {
-		args.To = ""
-	} else {
-		argstr, ok := obj[0].To.(string)
-		if !ok {
-			return NewInvalidTypeError("to", "is not a string")
-		}
-		args.To = argstr
-	}
-	if obj[0].From == nil {
-		args.From = ""
-	} else {
-		argstr, ok := obj[0].From.(string)
-		if !ok {
-			return NewInvalidTypeError("from", "is not a string")
-		}
-		args.From = argstr
-	}
-	// Construct the nested topic array
-	if obj[0].Topics != nil {
-		// Make sure we have an actual topic array
-		list, ok := obj[0].Topics.([]interface{})
-		if !ok {
-			return NewInvalidTypeError("topics", "is not an array")
-		}
-		// Iterate over each topic and handle nil, string or array
-		topics := make([][]string, len(list))
-		for idx, field := range list {
-			switch value := field.(type) {
-			case nil:
-				topics[idx] = []string{}
-
-			case string:
-				topics[idx] = []string{value}
-
-			case []interface{}:
-				topics[idx] = make([]string, len(value))
-				for i, nested := range value {
-					switch value := nested.(type) {
-					case nil:
-						topics[idx][i] = ""
-
-					case string:
-						topics[idx][i] = value
-
-					default:
-						return NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", idx, i), "is not a string")
-					}
-				}
-			default:
-				return NewInvalidTypeError(fmt.Sprintf("topic[%d]", idx), "not a string or array")
-			}
-		}
-		args.Topics = topics
-	}
-	return nil
-}
-
-type SubmitWorkArgs struct {
-	Nonce  uint64
-	Header string
-	Digest string
-}
-
-func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err = json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 3 {
-		return NewInsufficientParamsError(len(obj), 3)
-	}
-
-	var objstr string
-	var ok bool
-	if objstr, ok = obj[0].(string); !ok {
-		return NewInvalidTypeError("nonce", "not a string")
-	}
-
-	args.Nonce = common.String2Big(objstr).Uint64()
-	if objstr, ok = obj[1].(string); !ok {
-		return NewInvalidTypeError("header", "not a string")
-	}
-
-	args.Header = objstr
-
-	if objstr, ok = obj[2].(string); !ok {
-		return NewInvalidTypeError("digest", "not a string")
-	}
-
-	args.Digest = objstr
-
-	return nil
-}
-
-type SourceArgs struct {
-	Source string
-}
-
-func (args *SourceArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []interface{}
-	if err := json.Unmarshal(b, &obj); err != nil {
-		return NewDecodeParamError(err.Error())
-	}
-
-	if len(obj) < 1 {
-		return NewInsufficientParamsError(len(obj), 1)
-	}
-
-	arg0, ok := obj[0].(string)
-	if !ok {
-		return NewInvalidTypeError("source code", "not a string")
-	}
-	args.Source = arg0
-
-	return nil
-}
diff --git a/rpc/comms/comms.go b/rpc/comms/comms.go
index 244f5a7a6bf610be96794e2a9312bfbfc986d466..bfe625758271080a2c66c19ad63f1035a761538b 100644
--- a/rpc/comms/comms.go
+++ b/rpc/comms/comms.go
@@ -1,7 +1,111 @@
 package comms
 
+import (
+	"io"
+	"net"
+
+	"fmt"
+	"strings"
+
+	"strconv"
+
+	"github.com/ethereum/go-ethereum/logger"
+	"github.com/ethereum/go-ethereum/logger/glog"
+	"github.com/ethereum/go-ethereum/rpc/codec"
+	"github.com/ethereum/go-ethereum/rpc/shared"
+)
+
+const (
+	maxHttpSizeReqLength = 1024 * 1024 // 1MB
+)
+
+var (
+	// List with all API's which are offered over the in proc interface by default
+	DefaultInProcApis = shared.AllApis
+
+	// List with all API's which are offered over the IPC interface by default
+	DefaultIpcApis = shared.AllApis
+
+	// List with API's which are offered over thr HTTP/RPC interface by default
+	DefaultHttpRpcApis = strings.Join([]string{
+		shared.DbApiName, shared.EthApiName, shared.NetApiName, shared.Web3ApiName,
+	}, ",")
+)
+
 type EthereumClient interface {
+	// Close underlaying connection
 	Close()
+	// Send request
 	Send(interface{}) error
+	// Receive response
 	Recv() (interface{}, error)
+	// List with modules this client supports
+	SupportedModules() (map[string]string, error)
+}
+
+func handle(conn net.Conn, api shared.EthereumApi, c codec.Codec) {
+	codec := c.New(conn)
+
+	for {
+		req, err := codec.ReadRequest()
+		if err == io.EOF {
+			codec.Close()
+			return
+		} else if err != nil {
+			glog.V(logger.Error).Infof("comms recv err - %v\n", err)
+			codec.Close()
+			return
+		}
+
+		var rpcResponse interface{}
+		res, err := api.Execute(req)
+
+		rpcResponse = shared.NewRpcResponse(req.Id, req.Jsonrpc, res, err)
+		err = codec.WriteResponse(rpcResponse)
+		if err != nil {
+			glog.V(logger.Error).Infof("comms send err - %v\n", err)
+			codec.Close()
+			return
+		}
+	}
+}
+
+// Endpoint must be in the form of:
+// ${protocol}:${path}
+// e.g. ipc:/tmp/geth.ipc
+//      rpc:localhost:8545
+func ClientFromEndpoint(endpoint string, c codec.Codec) (EthereumClient, error) {
+	if strings.HasPrefix(endpoint, "ipc:") {
+		cfg := IpcConfig{
+			Endpoint: endpoint[4:],
+		}
+		return NewIpcClient(cfg, codec.JSON)
+	}
+
+	if strings.HasPrefix(endpoint, "rpc:") {
+		parts := strings.Split(endpoint, ":")
+		addr := "http://localhost"
+		port := uint(8545)
+		if len(parts) >= 3 {
+			addr = parts[1] + ":" + parts[2]
+		}
+
+		if len(parts) >= 4 {
+			p, err := strconv.Atoi(parts[3])
+
+			if err != nil {
+				return nil, err
+			}
+			port = uint(p)
+		}
+
+		cfg := HttpConfig{
+			ListenAddress: addr,
+			ListenPort:    port,
+		}
+
+		return NewHttpClient(cfg, codec.JSON), nil
+	}
+
+	return nil, fmt.Errorf("Invalid endpoint")
 }
diff --git a/rpc/comms/http.go b/rpc/comms/http.go
new file mode 100644
index 0000000000000000000000000000000000000000..ebee791bd1cdaa78fd1ab9d85f2d2b96e7eb7e07
--- /dev/null
+++ b/rpc/comms/http.go
@@ -0,0 +1,190 @@
+package comms
+
+import (
+	"fmt"
+	"net/http"
+	"strings"
+
+	"bytes"
+	"io/ioutil"
+
+	"github.com/ethereum/go-ethereum/logger"
+	"github.com/ethereum/go-ethereum/logger/glog"
+	"github.com/ethereum/go-ethereum/rpc/codec"
+	"github.com/ethereum/go-ethereum/rpc/shared"
+	"github.com/rs/cors"
+)
+
+var (
+	// main HTTP rpc listener
+	httpListener         *stoppableTCPListener
+	listenerStoppedError = fmt.Errorf("Listener has stopped")
+)
+
+type HttpConfig struct {
+	ListenAddress string
+	ListenPort    uint
+	CorsDomain    string
+}
+
+func StartHttp(cfg HttpConfig, codec codec.Codec, api shared.EthereumApi) error {
+	if httpListener != nil {
+		if fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort) != httpListener.Addr().String() {
+			return fmt.Errorf("RPC service already running on %s ", httpListener.Addr().String())
+		}
+		return nil // RPC service already running on given host/port
+	}
+
+	l, err := newStoppableTCPListener(fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort))
+	if err != nil {
+		glog.V(logger.Error).Infof("Can't listen on %s:%d: %v", cfg.ListenAddress, cfg.ListenPort, err)
+		return err
+	}
+	httpListener = l
+
+	var handler http.Handler
+	if len(cfg.CorsDomain) > 0 {
+		var opts cors.Options
+		opts.AllowedMethods = []string{"POST"}
+		opts.AllowedOrigins = strings.Split(cfg.CorsDomain, " ")
+
+		c := cors.New(opts)
+		handler = newStoppableHandler(c.Handler(gethHttpHandler(codec, api)), l.stop)
+	} else {
+		handler = newStoppableHandler(gethHttpHandler(codec, api), l.stop)
+	}
+
+	go http.Serve(l, handler)
+
+	return nil
+}
+
+func StopHttp() {
+	if httpListener != nil {
+		httpListener.Stop()
+		httpListener = nil
+	}
+}
+
+type httpClient struct {
+	address string
+	port    uint
+	codec   codec.ApiCoder
+	lastRes interface{}
+	lastErr error
+}
+
+// Create a new in process client
+func NewHttpClient(cfg HttpConfig, c codec.Codec) *httpClient {
+	return &httpClient{
+		address: cfg.ListenAddress,
+		port:    cfg.ListenPort,
+		codec:   c.New(nil),
+	}
+}
+
+func (self *httpClient) Close() {
+	// do nothing
+}
+
+func (self *httpClient) Send(req interface{}) error {
+	var body []byte
+	var err error
+
+	self.lastRes = nil
+	self.lastErr = nil
+
+	if body, err = self.codec.Encode(req); err != nil {
+		return err
+	}
+
+	httpReq, err := http.NewRequest("POST", fmt.Sprintf("%s:%d", self.address, self.port), bytes.NewBuffer(body))
+	if err != nil {
+		return err
+	}
+	httpReq.Header.Set("Content-Type", "application/json")
+
+	client := http.Client{}
+	resp, err := client.Do(httpReq)
+	if err != nil {
+		return err
+	}
+
+	defer resp.Body.Close()
+
+	if resp.Status == "200 OK" {
+		reply, _ := ioutil.ReadAll(resp.Body)
+		var rpcSuccessResponse shared.SuccessResponse
+		if err = self.codec.Decode(reply, &rpcSuccessResponse); err == nil {
+			self.lastRes = rpcSuccessResponse.Result
+			self.lastErr = err
+			return nil
+		} else {
+			var rpcErrorResponse shared.ErrorResponse
+			if err = self.codec.Decode(reply, &rpcErrorResponse); err == nil {
+				self.lastRes = rpcErrorResponse.Error
+				self.lastErr = err
+				return nil
+			} else {
+				return err
+			}
+		}
+	}
+
+	return fmt.Errorf("Not implemented")
+}
+
+func (self *httpClient) Recv() (interface{}, error) {
+	return self.lastRes, self.lastErr
+}
+
+func (self *httpClient) SupportedModules() (map[string]string, error) {
+	var body []byte
+	var err error
+
+	payload := shared.Request{
+		Id:      1,
+		Jsonrpc: "2.0",
+		Method:  "modules",
+	}
+
+	if body, err = self.codec.Encode(payload); err != nil {
+		return nil, err
+	}
+
+	req, err := http.NewRequest("POST", fmt.Sprintf("%s:%d", self.address, self.port), bytes.NewBuffer(body))
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Set("Content-Type", "application/json")
+
+	client := http.Client{}
+	resp, err := client.Do(req)
+	if err != nil {
+		return nil, err
+	}
+
+	defer resp.Body.Close()
+
+	if resp.Status == "200 OK" {
+		reply, _ := ioutil.ReadAll(resp.Body)
+		var rpcRes shared.SuccessResponse
+		if err = self.codec.Decode(reply, &rpcRes); err != nil {
+			return nil, err
+		}
+
+		result := make(map[string]string)
+		if modules, ok := rpcRes.Result.(map[string]interface{}); ok {
+			for a, v := range modules {
+				result[a] = fmt.Sprintf("%s", v)
+			}
+			return result, nil
+		}
+		err = fmt.Errorf("Unable to parse module response - %v", rpcRes.Result)
+	} else {
+		fmt.Printf("resp.Status = %s\n", resp.Status)
+		fmt.Printf("err = %v\n", err)
+	}
+
+	return nil, err
+}
diff --git a/rpc/comms/http_net.go b/rpc/comms/http_net.go
new file mode 100644
index 0000000000000000000000000000000000000000..acc5f99a95b51035ea28752e1316915bba300d36
--- /dev/null
+++ b/rpc/comms/http_net.go
@@ -0,0 +1,166 @@
+package comms
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net"
+	"net/http"
+	"time"
+
+	"github.com/ethereum/go-ethereum/logger"
+	"github.com/ethereum/go-ethereum/logger/glog"
+	"github.com/ethereum/go-ethereum/rpc/codec"
+	"github.com/ethereum/go-ethereum/rpc/shared"
+)
+
+// When https://github.com/golang/go/issues/4674 is implemented this could be replaced
+type stoppableTCPListener struct {
+	*net.TCPListener
+	stop chan struct{} // closed when the listener must stop
+}
+
+func newStoppableTCPListener(addr string) (*stoppableTCPListener, error) {
+	wl, err := net.Listen("tcp", addr)
+	if err != nil {
+		return nil, err
+	}
+
+	if tcpl, ok := wl.(*net.TCPListener); ok {
+		stop := make(chan struct{})
+		return &stoppableTCPListener{tcpl, stop}, nil
+	}
+
+	return nil, fmt.Errorf("Unable to create TCP listener for RPC service")
+}
+
+// Stop the listener and all accepted and still active connections.
+func (self *stoppableTCPListener) Stop() {
+	close(self.stop)
+}
+
+func (self *stoppableTCPListener) Accept() (net.Conn, error) {
+	for {
+		self.SetDeadline(time.Now().Add(time.Duration(1 * time.Second)))
+		c, err := self.TCPListener.AcceptTCP()
+
+		select {
+		case <-self.stop:
+			if c != nil { // accept timeout
+				c.Close()
+			}
+			self.TCPListener.Close()
+			return nil, listenerStoppedError
+		default:
+		}
+
+		if err != nil {
+			if netErr, ok := err.(net.Error); ok && netErr.Timeout() && netErr.Temporary() {
+				continue // regular timeout
+			}
+		}
+
+		return &closableConnection{c, self.stop}, err
+	}
+}
+
+type closableConnection struct {
+	*net.TCPConn
+	closed chan struct{}
+}
+
+func (self *closableConnection) Read(b []byte) (n int, err error) {
+	select {
+	case <-self.closed:
+		self.TCPConn.Close()
+		return 0, io.EOF
+	default:
+		return self.TCPConn.Read(b)
+	}
+}
+
+// Wraps the default handler and checks if the RPC service was stopped. In that case it returns an
+// error indicating that the service was stopped. This will only happen for connections which are
+// kept open (HTTP keep-alive) when the RPC service was shutdown.
+func newStoppableHandler(h http.Handler, stop chan struct{}) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		select {
+		case <-stop:
+			w.Header().Set("Content-Type", "application/json")
+			err := fmt.Errorf("RPC service stopped")
+			response := shared.NewRpcResponse(-1, shared.JsonRpcVersion, nil, err)
+			httpSend(w, response)
+		default:
+			h.ServeHTTP(w, r)
+		}
+	})
+}
+
+func httpSend(writer io.Writer, v interface{}) (n int, err error) {
+	var payload []byte
+	payload, err = json.MarshalIndent(v, "", "\t")
+	if err != nil {
+		glog.V(logger.Error).Infoln("Error marshalling JSON", err)
+		return 0, err
+	}
+	glog.V(logger.Detail).Infof("Sending payload: %s", payload)
+
+	return writer.Write(payload)
+}
+
+func gethHttpHandler(codec codec.Codec, a shared.EthereumApi) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+		w.Header().Set("Content-Type", "application/json")
+
+		// Limit request size to resist DoS
+		if req.ContentLength > maxHttpSizeReqLength {
+			err := fmt.Errorf("Request too large")
+			response := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32700, err)
+			httpSend(w, &response)
+			return
+		}
+
+		defer req.Body.Close()
+		payload, err := ioutil.ReadAll(req.Body)
+		if err != nil {
+			err := fmt.Errorf("Could not read request body")
+			response := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32700, err)
+			httpSend(w, &response)
+			return
+		}
+
+		c := codec.New(nil)
+		var rpcReq shared.Request
+		if err = c.Decode(payload, &rpcReq); err == nil {
+			reply, err := a.Execute(&rpcReq)
+			res := shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err)
+			httpSend(w, &res)
+			return
+		}
+
+		var reqBatch []shared.Request
+		if err = c.Decode(payload, &reqBatch); err == nil {
+			resBatch := make([]*interface{}, len(reqBatch))
+			resCount := 0
+
+			for i, rpcReq := range reqBatch {
+				reply, err := a.Execute(&rpcReq)
+				if rpcReq.Id != nil { // this leaves nil entries in the response batch for later removal
+					resBatch[i] = shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err)
+					resCount += 1
+				}
+			}
+
+			// make response omitting nil entries
+			resBatch = resBatch[:resCount]
+			httpSend(w, resBatch)
+			return
+		}
+
+		// invalid request
+		err = fmt.Errorf("Could not decode request")
+		res := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32600, err)
+		httpSend(w, res)
+	})
+}
diff --git a/rpc/comms/inproc.go b/rpc/comms/inproc.go
new file mode 100644
index 0000000000000000000000000000000000000000..5c84b8fd86d18ea184481ac151a93fc1f418c065
--- /dev/null
+++ b/rpc/comms/inproc.go
@@ -0,0 +1,66 @@
+package comms
+
+import (
+	"fmt"
+
+	"github.com/ethereum/go-ethereum/rpc/codec"
+	"github.com/ethereum/go-ethereum/rpc/shared"
+)
+
+type InProcClient struct {
+	api         shared.EthereumApi
+	codec       codec.Codec
+	lastId      interface{}
+	lastJsonrpc string
+	lastErr     error
+	lastRes     interface{}
+}
+
+// Create a new in process client
+func NewInProcClient(codec codec.Codec) *InProcClient {
+	return &InProcClient{
+		codec: codec,
+	}
+}
+
+func (self *InProcClient) Close() {
+	// do nothing
+}
+
+// Need to setup api support
+func (self *InProcClient) Initialize(offeredApi shared.EthereumApi) {
+	self.api = offeredApi
+}
+
+func (self *InProcClient) Send(req interface{}) error {
+	if r, ok := req.(*shared.Request); ok {
+		self.lastId = r.Id
+		self.lastJsonrpc = r.Jsonrpc
+		self.lastRes, self.lastErr = self.api.Execute(r)
+		return self.lastErr
+	}
+
+	return fmt.Errorf("Invalid request (%T)", req)
+}
+
+func (self *InProcClient) Recv() (interface{}, error) {
+	return self.lastRes, self.lastErr
+}
+
+func (self *InProcClient) SupportedModules() (map[string]string, error) {
+	req := shared.Request{
+		Id:      1,
+		Jsonrpc: "2.0",
+		Method:  "modules",
+	}
+
+	if res, err := self.api.Execute(&req); err == nil {
+		if result, ok := res.(map[string]string); ok {
+			return result, nil
+		}
+	} else {
+		return nil, err
+	}
+
+	return nil, fmt.Errorf("Invalid response")
+}
diff --git a/rpc/comms/ipc.go b/rpc/comms/ipc.go
index a75039d17f5d4e8c5c5e7b432d47981f39b04a84..068a1288fe3ee9431e090920743d4ef80bcc148f 100644
--- a/rpc/comms/ipc.go
+++ b/rpc/comms/ipc.go
@@ -1,8 +1,13 @@
 package comms
 
 import (
-	"github.com/ethereum/go-ethereum/rpc/api"
+	"fmt"
+	"net"
+
+	"encoding/json"
+
 	"github.com/ethereum/go-ethereum/rpc/codec"
+	"github.com/ethereum/go-ethereum/rpc/shared"
 )
 
 type IpcConfig struct {
@@ -10,19 +15,74 @@ type IpcConfig struct {
 }
 
 type ipcClient struct {
-	c codec.ApiCoder
+	endpoint string
+	codec    codec.Codec
+	coder    codec.ApiCoder
 }
 
 func (self *ipcClient) Close() {
-	self.c.Close()
+	self.coder.Close()
 }
 
 func (self *ipcClient) Send(req interface{}) error {
-	return self.c.WriteResponse(req)
+	var err error
+	if r, ok := req.(*shared.Request); ok {
+		if err = self.coder.WriteResponse(r); err != nil {
+			if _, ok := err.(*net.OpError); ok { // connection lost, retry once
+				if err = self.reconnect(); err == nil {
+					err = self.coder.WriteResponse(r)
+				}
+			}
+		}
+		return err
+	}
+
+	return fmt.Errorf("Invalid request (%T)", req)
 }
 
 func (self *ipcClient) Recv() (interface{}, error) {
-	return self.c.ReadResponse()
+	res, err := self.coder.ReadResponse()
+	if err != nil {
+		return nil, err
+	}
+
+	if r, ok := res.(shared.SuccessResponse); ok {
+		return r.Result, nil
+	}
+
+	if r, ok := res.(shared.ErrorResponse); ok {
+		return r.Error, nil
+	}
+
+	return res, err
+}
+
+func (self *ipcClient) SupportedModules() (map[string]string, error) {
+	req := shared.Request{
+		Id:      1,
+		Jsonrpc: "2.0",
+		Method:  "modules",
+	}
+
+	if err := self.coder.WriteResponse(req); err != nil {
+		return nil, err
+	}
+
+	res, err := self.coder.ReadResponse()
+	if err != nil {
+		return nil, err
+	}
+
+	if sucRes, ok := res.(shared.SuccessResponse); ok {
+		data, _ := json.Marshal(sucRes.Result)
+		modules := make(map[string]string)
+		err = json.Unmarshal(data, &modules)
+		if err == nil {
+			return modules, nil
+		}
+	}
+
+	return nil, fmt.Errorf("Invalid response")
 }
 
 // Create a new IPC client, UNIX domain socket on posix, named pipe on Windows
@@ -31,7 +91,6 @@ func NewIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) {
 }
 
 // Start IPC server
-func StartIpc(cfg IpcConfig, codec codec.Codec, apis ...api.EthereumApi) error {
-	offeredApi := api.Merge(apis...)
+func StartIpc(cfg IpcConfig, codec codec.Codec, offeredApi shared.EthereumApi) error {
 	return startIpc(cfg, codec, offeredApi)
 }
diff --git a/rpc/comms/ipc_unix.go b/rpc/comms/ipc_unix.go
index 5a94fd1e0ff97f7f47eb0a74191f3cf919b75454..295eb916b8a46171ea87d22a2d0ec178954705ea 100644
--- a/rpc/comms/ipc_unix.go
+++ b/rpc/comms/ipc_unix.go
@@ -3,13 +3,11 @@
 package comms
 
 import (
-	"io"
 	"net"
 	"os"
 
 	"github.com/ethereum/go-ethereum/logger"
 	"github.com/ethereum/go-ethereum/logger/glog"
-	"github.com/ethereum/go-ethereum/rpc/api"
 	"github.com/ethereum/go-ethereum/rpc/codec"
 	"github.com/ethereum/go-ethereum/rpc/shared"
 )
@@ -20,10 +18,20 @@ func newIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) {
 		return nil, err
 	}
 
-	return &ipcClient{codec.New(c)}, nil
+	return &ipcClient{cfg.Endpoint, codec, codec.New(c)}, nil
 }
 
-func startIpc(cfg IpcConfig, codec codec.Codec, api api.EthereumApi) error {
+func (self *ipcClient) reconnect() error {
+	self.coder.Close()
+	c, err := net.DialUnix("unix", nil, &net.UnixAddr{self.endpoint, "unix"})
+	if err == nil {
+		self.coder = self.codec.New(c)
+	}
+
+	return err
+}
+
+func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error {
 	os.Remove(cfg.Endpoint) // in case it still exists from a previous run
 
 	l, err := net.ListenUnix("unix", &net.UnixAddr{Name: cfg.Endpoint, Net: "unix"})
@@ -40,32 +48,7 @@ func startIpc(cfg IpcConfig, codec codec.Codec, api api.EthereumApi) error {
 				continue
 			}
 
-			go func(conn net.Conn) {
-				codec := codec.New(conn)
-
-				for {
-					req, err := codec.ReadRequest()
-					if err == io.EOF {
-						codec.Close()
-						return
-					} else if err != nil {
-						glog.V(logger.Error).Infof("IPC recv err - %v\n", err)
-						codec.Close()
-						return
-					}
-
-					var rpcResponse interface{}
-					res, err := api.Execute(req)
-
-					rpcResponse = shared.NewRpcResponse(req.Id, req.Jsonrpc, res, err)
-					err = codec.WriteResponse(rpcResponse)
-					if err != nil {
-						glog.V(logger.Error).Infof("IPC send err - %v\n", err)
-						codec.Close()
-						return
-					}
-				}
-			}(conn)
+			go handle(conn, api, codec)
 		}
 
 		os.Remove(cfg.Endpoint)
diff --git a/rpc/comms/ipc_windows.go b/rpc/comms/ipc_windows.go
index c48dfb7fb8a3b6ec8b1bbdc0507159cc802f7f2a..44c82ef8a62131d7a785a9af743c9205944c462a 100644
--- a/rpc/comms/ipc_windows.go
+++ b/rpc/comms/ipc_windows.go
@@ -14,7 +14,6 @@ import (
 
 	"github.com/ethereum/go-ethereum/logger"
 	"github.com/ethereum/go-ethereum/logger/glog"
-	"github.com/ethereum/go-ethereum/rpc/api"
 	"github.com/ethereum/go-ethereum/rpc/codec"
 	"github.com/ethereum/go-ethereum/rpc/shared"
 )
@@ -641,10 +640,18 @@ func newIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) {
 		return nil, err
 	}
 
-	return &ipcClient{codec.New(c)}, nil
+	return &ipcClient{cfg.Endpoint, codec, codec.New(c)}, nil
 }
 
-func startIpc(cfg IpcConfig, codec codec.Codec, api api.EthereumApi) error {
+func (self *ipcClient) reconnect() error {
+	c, err := Dial(self.endpoint)
+	if err == nil {
+		self.coder = self.codec.New(c)
+	}
+	return err
+}
+
+func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error {
 	os.Remove(cfg.Endpoint) // in case it still exists from a previous run
 
 	l, err := Listen(cfg.Endpoint)
diff --git a/rpc/http.go b/rpc/http.go
deleted file mode 100644
index f37e102f5d2d8e3ee2863bf360fd25e1c17d27c7..0000000000000000000000000000000000000000
--- a/rpc/http.go
+++ /dev/null
@@ -1,163 +0,0 @@
-package rpc
-
-import (
-	"encoding/json"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"strings"
-
-	"github.com/ethereum/go-ethereum/logger"
-	"github.com/ethereum/go-ethereum/logger/glog"
-	"github.com/ethereum/go-ethereum/xeth"
-	"github.com/rs/cors"
-)
-
-var rpclistener *stoppableTCPListener
-
-const (
-	jsonrpcver       = "2.0"
-	maxSizeReqLength = 1024 * 1024 // 1MB
-)
-
-func Start(pipe *xeth.XEth, config RpcConfig) error {
-	if rpclistener != nil {
-		if fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort) != rpclistener.Addr().String() {
-			return fmt.Errorf("RPC service already running on %s ", rpclistener.Addr().String())
-		}
-		return nil // RPC service already running on given host/port
-	}
-
-	l, err := newStoppableTCPListener(fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort))
-	if err != nil {
-		glog.V(logger.Error).Infof("Can't listen on %s:%d: %v", config.ListenAddress, config.ListenPort, err)
-		return err
-	}
-	rpclistener = l
-
-	var handler http.Handler
-	if len(config.CorsDomain) > 0 {
-		var opts cors.Options
-		opts.AllowedMethods = []string{"POST"}
-		opts.AllowedOrigins = strings.Split(config.CorsDomain, " ")
-
-		c := cors.New(opts)
-		handler = newStoppableHandler(c.Handler(JSONRPC(pipe)), l.stop)
-	} else {
-		handler = newStoppableHandler(JSONRPC(pipe), l.stop)
-	}
-
-	go http.Serve(l, handler)
-
-	return nil
-}
-
-func Stop() error {
-	if rpclistener != nil {
-		rpclistener.Stop()
-		rpclistener = nil
-	}
-
-	return nil
-}
-
-// JSONRPC returns a handler that implements the Ethereum JSON-RPC API.
-func JSONRPC(pipe *xeth.XEth) http.Handler {
-	api := NewEthereumApi(pipe)
-
-	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
-		w.Header().Set("Content-Type", "application/json")
-
-		// Limit request size to resist DoS
-		if req.ContentLength > maxSizeReqLength {
-			jsonerr := &RpcErrorObject{-32700, "Request too large"}
-			send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr})
-			return
-		}
-
-		// Read request body
-		defer req.Body.Close()
-		body, err := ioutil.ReadAll(req.Body)
-		if err != nil {
-			jsonerr := &RpcErrorObject{-32700, "Could not read request body"}
-			send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr})
-		}
-
-		// Try to parse the request as a single
-		var reqSingle RpcRequest
-		if err := json.Unmarshal(body, &reqSingle); err == nil {
-			response := RpcResponse(api, &reqSingle)
-			if reqSingle.Id != nil {
-				send(w, &response)
-			}
-			return
-		}
-
-		// Try to parse the request to batch
-		var reqBatch []RpcRequest
-		if err := json.Unmarshal(body, &reqBatch); err == nil {
-			// Build response batch
-			resBatch := make([]*interface{}, len(reqBatch))
-			resCount := 0
-
-			for i, request := range reqBatch {
-				response := RpcResponse(api, &request)
-				// this leaves nil entries in the response batch for later removal
-				if request.Id != nil {
-					resBatch[i] = response
-					resCount = resCount + 1
-				}
-			}
-
-			// make response omitting nil entries
-			respBatchComp := make([]*interface{}, resCount)
-			for _, v := range resBatch {
-				if v != nil {
-					respBatchComp[len(respBatchComp)-resCount] = v
-					resCount = resCount - 1
-				}
-			}
-
-			send(w, respBatchComp)
-			return
-		}
-
-		// Not a batch or single request, error
-		jsonerr := &RpcErrorObject{-32600, "Could not decode request"}
-		send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr})
-	})
-}
-
-func RpcResponse(api *EthereumApi, request *RpcRequest) *interface{} {
-	var reply, response interface{}
-	reserr := api.GetRequestReply(request, &reply)
-	switch reserr.(type) {
-	case nil:
-		response = &RpcSuccessResponse{Jsonrpc: jsonrpcver, Id: request.Id, Result: reply}
-	case *NotImplementedError, *NotAvailableError:
-		jsonerr := &RpcErrorObject{-32601, reserr.Error()}
-		response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
-	case *DecodeParamError, *InsufficientParamsError, *ValidationError, *InvalidTypeError:
-		jsonerr := &RpcErrorObject{-32602, reserr.Error()}
-		response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
-	default:
-		jsonerr := &RpcErrorObject{-32603, reserr.Error()}
-		response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
-	}
-
-	glog.V(logger.Detail).Infof("Generated response: %T %s", response, response)
-	return &response
-}
-
-func send(writer io.Writer, v interface{}) (n int, err error) {
-	var payload []byte
-	payload, err = json.MarshalIndent(v, "", "\t")
-	if err != nil {
-		glog.V(logger.Error).Infoln("Error marshalling JSON", err)
-		return 0, err
-	}
-	glog.V(logger.Detail).Infof("Sending payload: %s", payload)
-
-	return writer.Write(payload)
-}
diff --git a/rpc/jeth.go b/rpc/jeth.go
index e578775bb62fe5e249067ff22270bb6cccc5f9c5..33fcd6efd66076e4fee9c4fb32a0369376717149 100644
--- a/rpc/jeth.go
+++ b/rpc/jeth.go
@@ -2,30 +2,26 @@ package rpc
 
 import (
 	"encoding/json"
-	"fmt"
-
-	"reflect"
 
 	"github.com/ethereum/go-ethereum/jsre"
-	"github.com/ethereum/go-ethereum/rpc/codec"
 	"github.com/ethereum/go-ethereum/rpc/comms"
 	"github.com/ethereum/go-ethereum/rpc/shared"
 	"github.com/robertkrimen/otto"
 )
 
 type Jeth struct {
-	ethApi  *EthereumApi
-	re      *jsre.JSRE
-	ipcpath string
+	ethApi shared.EthereumApi
+	re     *jsre.JSRE
+	client comms.EthereumClient
 }
 
-func NewJeth(ethApi *EthereumApi, re *jsre.JSRE, ipcpath string) *Jeth {
-	return &Jeth{ethApi, re, ipcpath}
+func NewJeth(ethApi shared.EthereumApi, re *jsre.JSRE, client comms.EthereumClient) *Jeth {
+	return &Jeth{ethApi, re, client}
 }
 
 func (self *Jeth) err(call otto.FunctionCall, code int, msg string, id interface{}) (response otto.Value) {
-	rpcerr := &RpcErrorObject{code, msg}
-	call.Otto.Set("ret_jsonrpc", jsonrpcver)
+	rpcerr := &shared.ErrorObject{code, msg}
+	call.Otto.Set("ret_jsonrpc", shared.JsonRpcVersion)
 	call.Otto.Set("ret_id", id)
 	call.Otto.Set("ret_error", rpcerr)
 	response, _ = call.Otto.Run(`
@@ -41,11 +37,11 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
 	}
 
 	jsonreq, err := json.Marshal(reqif)
-	var reqs []RpcRequest
+	var reqs []shared.Request
 	batch := true
 	err = json.Unmarshal(jsonreq, &reqs)
 	if err != nil {
-		reqs = make([]RpcRequest, 1)
+		reqs = make([]shared.Request, 1)
 		err = json.Unmarshal(jsonreq, &reqs[0])
 		batch = false
 	}
@@ -55,12 +51,16 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
 
 	for i, req := range reqs {
 		var respif interface{}
-		err = self.ethApi.GetRequestReply(&req, &respif)
+		err := self.client.Send(&req)
+		if err != nil {
+			return self.err(call, -32603, err.Error(), req.Id)
+		}
+		respif, err = self.client.Recv()
 		if err != nil {
-			fmt.Println("Error response:", err)
 			return self.err(call, -32603, err.Error(), req.Id)
 		}
-		call.Otto.Set("ret_jsonrpc", jsonrpcver)
+
+		call.Otto.Set("ret_jsonrpc", shared.JsonRpcVersion)
 		call.Otto.Set("ret_id", req.Id)
 
 		res, _ := json.Marshal(respif)
@@ -87,85 +87,3 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
 
 	return
 }
-
-func (self *Jeth) SendIpc(call otto.FunctionCall) (response otto.Value) {
-	reqif, err := call.Argument(0).Export()
-	if err != nil {
-		return self.err(call, -32700, err.Error(), nil)
-	}
-
-	client, err := comms.NewIpcClient(comms.IpcConfig{self.ipcpath}, codec.JSON)
-	if err != nil {
-		fmt.Println("Unable to connect to geth.")
-		return self.err(call, -32603, err.Error(), -1)
-	}
-	defer client.Close()
-
-	jsonreq, err := json.Marshal(reqif)
-	var reqs []RpcRequest
-	batch := true
-	err = json.Unmarshal(jsonreq, &reqs)
-	if err != nil {
-		reqs = make([]RpcRequest, 1)
-		err = json.Unmarshal(jsonreq, &reqs[0])
-		batch = false
-	}
-
-	call.Otto.Set("response_len", len(reqs))
-	call.Otto.Run("var ret_response = new Array(response_len);")
-
-	for i, req := range reqs {
-		err := client.Send(&req)
-		if err != nil {
-			fmt.Println("Error send request:", err)
-			return self.err(call, -32603, err.Error(), req.Id)
-		}
-
-		respif, err := client.Recv()
-		if err != nil {
-			fmt.Println("Error recv response:", err)
-			return self.err(call, -32603, err.Error(), req.Id)
-		}
-
-		if res, ok := respif.(shared.SuccessResponse); ok {
-			call.Otto.Set("ret_id", res.Id)
-			call.Otto.Set("ret_jsonrpc", res.Jsonrpc)
-			resObj, _ := json.Marshal(res.Result)
-			call.Otto.Set("ret_result", string(resObj))
-			call.Otto.Set("response_idx", i)
-
-			response, err = call.Otto.Run(`
-				ret_response[response_idx] = { jsonrpc: ret_jsonrpc, id: ret_id, result: JSON.parse(ret_result) };
-			`)
-		} else if res, ok := respif.(shared.ErrorResponse); ok {
-			fmt.Printf("Error: %s (%d)\n", res.Error.Message, res.Error.Code)
-
-			call.Otto.Set("ret_id", res.Id)
-			call.Otto.Set("ret_jsonrpc", res.Jsonrpc)
-			call.Otto.Set("ret_error", res.Error)
-			call.Otto.Set("response_idx", i)
-
-			response, _ = call.Otto.Run(`
-				ret_response = { jsonrpc: ret_jsonrpc, id: ret_id, error: ret_error };
-			`)
-			return
-		} else {
-			fmt.Printf("unexpected response\n", reflect.TypeOf(respif))
-		}
-	}
-
-	if !batch {
-		call.Otto.Run("ret_response = ret_response[0];")
-	}
-
-	if call.Argument(1).IsObject() {
-		call.Otto.Set("callback", call.Argument(1))
-		call.Otto.Run(`
-	    if (Object.prototype.toString.call(callback) == '[object Function]') {
-			callback(null, ret_response);
-		}
-		`)
-	}
-
-	return
-}
diff --git a/rpc/responses.go b/rpc/responses.go
deleted file mode 100644
index 9fdf60c022e73663a168af9dd1aee552de0f0032..0000000000000000000000000000000000000000
--- a/rpc/responses.go
+++ /dev/null
@@ -1,316 +0,0 @@
-package rpc
-
-import (
-	"encoding/json"
-
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/core/state"
-	"github.com/ethereum/go-ethereum/core/types"
-)
-
-type BlockRes struct {
-	fullTx bool
-
-	BlockNumber     *hexnum           `json:"number"`
-	BlockHash       *hexdata          `json:"hash"`
-	ParentHash      *hexdata          `json:"parentHash"`
-	Nonce           *hexdata          `json:"nonce"`
-	Sha3Uncles      *hexdata          `json:"sha3Uncles"`
-	LogsBloom       *hexdata          `json:"logsBloom"`
-	TransactionRoot *hexdata          `json:"transactionsRoot"`
-	StateRoot       *hexdata          `json:"stateRoot"`
-	Miner           *hexdata          `json:"miner"`
-	Difficulty      *hexnum           `json:"difficulty"`
-	TotalDifficulty *hexnum           `json:"totalDifficulty"`
-	Size            *hexnum           `json:"size"`
-	ExtraData       *hexdata          `json:"extraData"`
-	GasLimit        *hexnum           `json:"gasLimit"`
-	GasUsed         *hexnum           `json:"gasUsed"`
-	UnixTimestamp   *hexnum           `json:"timestamp"`
-	Transactions    []*TransactionRes `json:"transactions"`
-	Uncles          []*UncleRes       `json:"uncles"`
-}
-
-func (b *BlockRes) MarshalJSON() ([]byte, error) {
-	if b.fullTx {
-		var ext struct {
-			BlockNumber     *hexnum           `json:"number"`
-			BlockHash       *hexdata          `json:"hash"`
-			ParentHash      *hexdata          `json:"parentHash"`
-			Nonce           *hexdata          `json:"nonce"`
-			Sha3Uncles      *hexdata          `json:"sha3Uncles"`
-			LogsBloom       *hexdata          `json:"logsBloom"`
-			TransactionRoot *hexdata          `json:"transactionsRoot"`
-			StateRoot       *hexdata          `json:"stateRoot"`
-			Miner           *hexdata          `json:"miner"`
-			Difficulty      *hexnum           `json:"difficulty"`
-			TotalDifficulty *hexnum           `json:"totalDifficulty"`
-			Size            *hexnum           `json:"size"`
-			ExtraData       *hexdata          `json:"extraData"`
-			GasLimit        *hexnum           `json:"gasLimit"`
-			GasUsed         *hexnum           `json:"gasUsed"`
-			UnixTimestamp   *hexnum           `json:"timestamp"`
-			Transactions    []*TransactionRes `json:"transactions"`
-			Uncles          []*hexdata        `json:"uncles"`
-		}
-
-		ext.BlockNumber = b.BlockNumber
-		ext.BlockHash = b.BlockHash
-		ext.ParentHash = b.ParentHash
-		ext.Nonce = b.Nonce
-		ext.Sha3Uncles = b.Sha3Uncles
-		ext.LogsBloom = b.LogsBloom
-		ext.TransactionRoot = b.TransactionRoot
-		ext.StateRoot = b.StateRoot
-		ext.Miner = b.Miner
-		ext.Difficulty = b.Difficulty
-		ext.TotalDifficulty = b.TotalDifficulty
-		ext.Size = b.Size
-		ext.ExtraData = b.ExtraData
-		ext.GasLimit = b.GasLimit
-		ext.GasUsed = b.GasUsed
-		ext.UnixTimestamp = b.UnixTimestamp
-		ext.Transactions = b.Transactions
-		ext.Uncles = make([]*hexdata, len(b.Uncles))
-		for i, u := range b.Uncles {
-			ext.Uncles[i] = u.BlockHash
-		}
-		return json.Marshal(ext)
-	} else {
-		var ext struct {
-			BlockNumber     *hexnum    `json:"number"`
-			BlockHash       *hexdata   `json:"hash"`
-			ParentHash      *hexdata   `json:"parentHash"`
-			Nonce           *hexdata   `json:"nonce"`
-			Sha3Uncles      *hexdata   `json:"sha3Uncles"`
-			LogsBloom       *hexdata   `json:"logsBloom"`
-			TransactionRoot *hexdata   `json:"transactionsRoot"`
-			StateRoot       *hexdata   `json:"stateRoot"`
-			Miner           *hexdata   `json:"miner"`
-			Difficulty      *hexnum    `json:"difficulty"`
-			TotalDifficulty *hexnum    `json:"totalDifficulty"`
-			Size            *hexnum    `json:"size"`
-			ExtraData       *hexdata   `json:"extraData"`
-			GasLimit        *hexnum    `json:"gasLimit"`
-			GasUsed         *hexnum    `json:"gasUsed"`
-			UnixTimestamp   *hexnum    `json:"timestamp"`
-			Transactions    []*hexdata `json:"transactions"`
-			Uncles          []*hexdata `json:"uncles"`
-		}
-
-		ext.BlockNumber = b.BlockNumber
-		ext.BlockHash = b.BlockHash
-		ext.ParentHash = b.ParentHash
-		ext.Nonce = b.Nonce
-		ext.Sha3Uncles = b.Sha3Uncles
-		ext.LogsBloom = b.LogsBloom
-		ext.TransactionRoot = b.TransactionRoot
-		ext.StateRoot = b.StateRoot
-		ext.Miner = b.Miner
-		ext.Difficulty = b.Difficulty
-		ext.TotalDifficulty = b.TotalDifficulty
-		ext.Size = b.Size
-		ext.ExtraData = b.ExtraData
-		ext.GasLimit = b.GasLimit
-		ext.GasUsed = b.GasUsed
-		ext.UnixTimestamp = b.UnixTimestamp
-		ext.Transactions = make([]*hexdata, len(b.Transactions))
-		for i, tx := range b.Transactions {
-			ext.Transactions[i] = tx.Hash
-		}
-		ext.Uncles = make([]*hexdata, len(b.Uncles))
-		for i, u := range b.Uncles {
-			ext.Uncles[i] = u.BlockHash
-		}
-		return json.Marshal(ext)
-	}
-}
-
-func NewBlockRes(block *types.Block, fullTx bool) *BlockRes {
-	if block == nil {
-		return nil
-	}
-
-	res := new(BlockRes)
-	res.fullTx = fullTx
-	res.BlockNumber = newHexNum(block.Number())
-	res.BlockHash = newHexData(block.Hash())
-	res.ParentHash = newHexData(block.ParentHash())
-	res.Nonce = newHexData(block.Nonce())
-	res.Sha3Uncles = newHexData(block.Header().UncleHash)
-	res.LogsBloom = newHexData(block.Bloom())
-	res.TransactionRoot = newHexData(block.Header().TxHash)
-	res.StateRoot = newHexData(block.Root())
-	res.Miner = newHexData(block.Header().Coinbase)
-	res.Difficulty = newHexNum(block.Difficulty())
-	res.TotalDifficulty = newHexNum(block.Td)
-	res.Size = newHexNum(block.Size().Int64())
-	res.ExtraData = newHexData(block.Header().Extra)
-	res.GasLimit = newHexNum(block.GasLimit())
-	res.GasUsed = newHexNum(block.GasUsed())
-	res.UnixTimestamp = newHexNum(block.Time())
-
-	res.Transactions = make([]*TransactionRes, len(block.Transactions()))
-	for i, tx := range block.Transactions() {
-		res.Transactions[i] = NewTransactionRes(tx)
-		res.Transactions[i].BlockHash = res.BlockHash
-		res.Transactions[i].BlockNumber = res.BlockNumber
-		res.Transactions[i].TxIndex = newHexNum(i)
-	}
-
-	res.Uncles = make([]*UncleRes, len(block.Uncles()))
-	for i, uncle := range block.Uncles() {
-		res.Uncles[i] = NewUncleRes(uncle)
-	}
-
-	return res
-}
-
-type TransactionRes struct {
-	Hash        *hexdata `json:"hash"`
-	Nonce       *hexnum  `json:"nonce"`
-	BlockHash   *hexdata `json:"blockHash"`
-	BlockNumber *hexnum  `json:"blockNumber"`
-	TxIndex     *hexnum  `json:"transactionIndex"`
-	From        *hexdata `json:"from"`
-	To          *hexdata `json:"to"`
-	Value       *hexnum  `json:"value"`
-	Gas         *hexnum  `json:"gas"`
-	GasPrice    *hexnum  `json:"gasPrice"`
-	Input       *hexdata `json:"input"`
-}
-
-func NewTransactionRes(tx *types.Transaction) *TransactionRes {
-	if tx == nil {
-		return nil
-	}
-
-	var v = new(TransactionRes)
-	v.Hash = newHexData(tx.Hash())
-	v.Nonce = newHexNum(tx.Nonce())
-	// v.BlockHash =
-	// v.BlockNumber =
-	// v.TxIndex =
-	from, _ := tx.From()
-	v.From = newHexData(from)
-	v.To = newHexData(tx.To())
-	v.Value = newHexNum(tx.Value())
-	v.Gas = newHexNum(tx.Gas())
-	v.GasPrice = newHexNum(tx.GasPrice())
-	v.Input = newHexData(tx.Data())
-	return v
-}
-
-type UncleRes struct {
-	BlockNumber     *hexnum  `json:"number"`
-	BlockHash       *hexdata `json:"hash"`
-	ParentHash      *hexdata `json:"parentHash"`
-	Nonce           *hexdata `json:"nonce"`
-	Sha3Uncles      *hexdata `json:"sha3Uncles"`
-	ReceiptHash     *hexdata `json:"receiptHash"`
-	LogsBloom       *hexdata `json:"logsBloom"`
-	TransactionRoot *hexdata `json:"transactionsRoot"`
-	StateRoot       *hexdata `json:"stateRoot"`
-	Miner           *hexdata `json:"miner"`
-	Difficulty      *hexnum  `json:"difficulty"`
-	ExtraData       *hexdata `json:"extraData"`
-	GasLimit        *hexnum  `json:"gasLimit"`
-	GasUsed         *hexnum  `json:"gasUsed"`
-	UnixTimestamp   *hexnum  `json:"timestamp"`
-}
-
-func NewUncleRes(h *types.Header) *UncleRes {
-	if h == nil {
-		return nil
-	}
-
-	var v = new(UncleRes)
-	v.BlockNumber = newHexNum(h.Number)
-	v.BlockHash = newHexData(h.Hash())
-	v.ParentHash = newHexData(h.ParentHash)
-	v.Sha3Uncles = newHexData(h.UncleHash)
-	v.Nonce = newHexData(h.Nonce[:])
-	v.LogsBloom = newHexData(h.Bloom)
-	v.TransactionRoot = newHexData(h.TxHash)
-	v.StateRoot = newHexData(h.Root)
-	v.Miner = newHexData(h.Coinbase)
-	v.Difficulty = newHexNum(h.Difficulty)
-	v.ExtraData = newHexData(h.Extra)
-	v.GasLimit = newHexNum(h.GasLimit)
-	v.GasUsed = newHexNum(h.GasUsed)
-	v.UnixTimestamp = newHexNum(h.Time)
-	v.ReceiptHash = newHexData(h.ReceiptHash)
-
-	return v
-}
-
-// type FilterLogRes struct {
-// 	Hash             string `json:"hash"`
-// 	Address          string `json:"address"`
-// 	Data             string `json:"data"`
-// 	BlockNumber      string `json:"blockNumber"`
-// 	TransactionHash  string `json:"transactionHash"`
-// 	BlockHash        string `json:"blockHash"`
-// 	TransactionIndex string `json:"transactionIndex"`
-// 	LogIndex         string `json:"logIndex"`
-// }
-
-// type FilterWhisperRes struct {
-// 	Hash       string `json:"hash"`
-// 	From       string `json:"from"`
-// 	To         string `json:"to"`
-// 	Expiry     string `json:"expiry"`
-// 	Sent       string `json:"sent"`
-// 	Ttl        string `json:"ttl"`
-// 	Topics     string `json:"topics"`
-// 	Payload    string `json:"payload"`
-// 	WorkProved string `json:"workProved"`
-// }
-
-type LogRes struct {
-	Address          *hexdata   `json:"address"`
-	Topics           []*hexdata `json:"topics"`
-	Data             *hexdata   `json:"data"`
-	BlockNumber      *hexnum    `json:"blockNumber"`
-	LogIndex         *hexnum    `json:"logIndex"`
-	BlockHash        *hexdata   `json:"blockHash"`
-	TransactionHash  *hexdata   `json:"transactionHash"`
-	TransactionIndex *hexnum    `json:"transactionIndex"`
-}
-
-func NewLogRes(log *state.Log) LogRes {
-	var l LogRes
-	l.Topics = make([]*hexdata, len(log.Topics))
-	for j, topic := range log.Topics {
-		l.Topics[j] = newHexData(topic)
-	}
-	l.Address = newHexData(log.Address)
-	l.Data = newHexData(log.Data)
-	l.BlockNumber = newHexNum(log.Number)
-	l.LogIndex = newHexNum(log.Index)
-	l.TransactionHash = newHexData(log.TxHash)
-	l.TransactionIndex = newHexNum(log.TxIndex)
-	l.BlockHash = newHexData(log.BlockHash)
-
-	return l
-}
-
-func NewLogsRes(logs state.Logs) (ls []LogRes) {
-	ls = make([]LogRes, len(logs))
-
-	for i, log := range logs {
-		ls[i] = NewLogRes(log)
-	}
-
-	return
-}
-
-func NewHashesRes(hs []common.Hash) []string {
-	hashes := make([]string, len(hs))
-
-	for i, hash := range hs {
-		hashes[i] = hash.Hex()
-	}
-
-	return hashes
-}
diff --git a/rpc/responses_test.go b/rpc/responses_test.go
deleted file mode 100644
index 66323e5f59407248bef735699036eaf26f604c6a..0000000000000000000000000000000000000000
--- a/rpc/responses_test.go
+++ /dev/null
@@ -1,295 +0,0 @@
-package rpc
-
-import (
-	"encoding/json"
-	"fmt"
-	"math/big"
-	"regexp"
-	"testing"
-
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/core/state"
-	"github.com/ethereum/go-ethereum/core/types"
-)
-
-const (
-	reHash       = `"0x[0-9a-f]{64}"`                    // 32 bytes
-	reHashOpt    = `"(0x[0-9a-f]{64})"|null`             // 32 bytes or null
-	reAddress    = `"0x[0-9a-f]{40}"`                    // 20 bytes
-	reAddressOpt = `"0x[0-9a-f]{40}"|null`               // 20 bytes or null
-	reNum        = `"0x([1-9a-f][0-9a-f]{0,15})|0"`      // must not have left-padded zeros
-	reNumNonZero = `"0x([1-9a-f][0-9a-f]{0,15})"`        // non-zero required must not have left-padded zeros
-	reNumOpt     = `"0x([1-9a-f][0-9a-f]{0,15})|0"|null` // must not have left-padded zeros or null
-	reData       = `"0x[0-9a-f]*"`                       // can be "empty"
-	// reListHash   = `[("\w":"0x[0-9a-f]{64}",?)*]`
-	// reListObj    = `[("\w":(".+"|null),?)*]`
-)
-
-func TestNewBlockRes(t *testing.T) {
-	tests := map[string]string{
-		"number":           reNum,
-		"hash":             reHash,
-		"parentHash":       reHash,
-		"nonce":            reData,
-		"sha3Uncles":       reHash,
-		"logsBloom":        reData,
-		"transactionsRoot": reHash,
-		"stateRoot":        reHash,
-		"miner":            reAddress,
-		"difficulty":       `"0x1"`,
-		"totalDifficulty":  reNum,
-		"size":             reNumNonZero,
-		"extraData":        reData,
-		"gasLimit":         reNum,
-		// "minGasPrice":  "0x",
-		"gasUsed":   reNum,
-		"timestamp": reNum,
-		// "transactions": reListHash,
-		// "uncles":       reListHash,
-	}
-
-	block := makeBlock()
-	v := NewBlockRes(block, false)
-	j, _ := json.Marshal(v)
-
-	for k, re := range tests {
-		match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
-		if !match {
-			t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j))
-		}
-	}
-}
-
-func TestNewBlockResTxFull(t *testing.T) {
-	tests := map[string]string{
-		"number":           reNum,
-		"hash":             reHash,
-		"parentHash":       reHash,
-		"nonce":            reData,
-		"sha3Uncles":       reHash,
-		"logsBloom":        reData,
-		"transactionsRoot": reHash,
-		"stateRoot":        reHash,
-		"miner":            reAddress,
-		"difficulty":       `"0x1"`,
-		"totalDifficulty":  reNum,
-		"size":             reNumNonZero,
-		"extraData":        reData,
-		"gasLimit":         reNum,
-		// "minGasPrice":  "0x",
-		"gasUsed":   reNum,
-		"timestamp": reNum,
-		// "transactions": reListHash,
-		// "uncles":       reListHash,
-	}
-
-	block := makeBlock()
-	v := NewBlockRes(block, true)
-	j, _ := json.Marshal(v)
-
-	for k, re := range tests {
-		match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
-		if !match {
-			t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j))
-		}
-	}
-}
-
-func TestBlockNil(t *testing.T) {
-	var block *types.Block
-	block = nil
-	u := NewBlockRes(block, false)
-	j, _ := json.Marshal(u)
-	if string(j) != "null" {
-		t.Errorf("Expected null but got %v", string(j))
-	}
-}
-
-func TestNewTransactionRes(t *testing.T) {
-	to := common.HexToAddress("0x02")
-	amount := big.NewInt(1)
-	gasAmount := big.NewInt(1)
-	gasPrice := big.NewInt(1)
-	data := []byte{1, 2, 3}
-	tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data)
-
-	tests := map[string]string{
-		"hash":             reHash,
-		"nonce":            reNum,
-		"blockHash":        reHashOpt,
-		"blockNum":         reNumOpt,
-		"transactionIndex": reNumOpt,
-		"from":             reAddress,
-		"to":               reAddressOpt,
-		"value":            reNum,
-		"gas":              reNum,
-		"gasPrice":         reNum,
-		"input":            reData,
-	}
-
-	v := NewTransactionRes(tx)
-	v.BlockHash = newHexData(common.HexToHash("0x030201"))
-	v.BlockNumber = newHexNum(5)
-	v.TxIndex = newHexNum(0)
-	j, _ := json.Marshal(v)
-	for k, re := range tests {
-		match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
-		if !match {
-			t.Error(fmt.Sprintf("`%s` output json does not match format %s. Source %s", k, re, j))
-		}
-	}
-
-}
-
-func TestTransactionNil(t *testing.T) {
-	var tx *types.Transaction
-	tx = nil
-	u := NewTransactionRes(tx)
-	j, _ := json.Marshal(u)
-	if string(j) != "null" {
-		t.Errorf("Expected null but got %v", string(j))
-	}
-}
-
-func TestNewUncleRes(t *testing.T) {
-	header := makeHeader()
-	u := NewUncleRes(header)
-	tests := map[string]string{
-		"number":           reNum,
-		"hash":             reHash,
-		"parentHash":       reHash,
-		"nonce":            reData,
-		"sha3Uncles":       reHash,
-		"receiptHash":      reHash,
-		"transactionsRoot": reHash,
-		"stateRoot":        reHash,
-		"miner":            reAddress,
-		"difficulty":       reNum,
-		"extraData":        reData,
-		"gasLimit":         reNum,
-		"gasUsed":          reNum,
-		"timestamp":        reNum,
-	}
-
-	j, _ := json.Marshal(u)
-	for k, re := range tests {
-		match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
-		if !match {
-			t.Error(fmt.Sprintf("`%s` output json does not match format %s. Source %s", k, re, j))
-		}
-	}
-}
-
-func TestUncleNil(t *testing.T) {
-	var header *types.Header
-	header = nil
-	u := NewUncleRes(header)
-	j, _ := json.Marshal(u)
-	if string(j) != "null" {
-		t.Errorf("Expected null but got %v", string(j))
-	}
-}
-
-func TestNewLogRes(t *testing.T) {
-	log := makeStateLog(0)
-	tests := map[string]string{
-		"address": reAddress,
-		// "topics": "[.*]"
-		"data":        reData,
-		"blockNumber": reNum,
-		// "hash":             reHash,
-		// "logIndex":         reNum,
-		// "blockHash":        reHash,
-		// "transactionHash":  reHash,
-		"transactionIndex": reNum,
-	}
-
-	v := NewLogRes(log)
-	j, _ := json.Marshal(v)
-
-	for k, re := range tests {
-		match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
-		if !match {
-			t.Error(fmt.Sprintf("`%s` output json does not match format %s. Got %s", k, re, j))
-		}
-	}
-
-}
-
-func TestNewLogsRes(t *testing.T) {
-	logs := make([]*state.Log, 3)
-	logs[0] = makeStateLog(1)
-	logs[1] = makeStateLog(2)
-	logs[2] = makeStateLog(3)
-	tests := map[string]string{}
-
-	v := NewLogsRes(logs)
-	j, _ := json.Marshal(v)
-
-	for k, re := range tests {
-		match, _ := regexp.MatchString(fmt.Sprintf(`[{.*"%s":%s.*}]`, k, re), string(j))
-		if !match {
-			t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j))
-		}
-	}
-
-}
-
-func makeStateLog(num int) *state.Log {
-	address := common.HexToAddress("0x0")
-	data := []byte{1, 2, 3}
-	number := uint64(num)
-	topics := make([]common.Hash, 3)
-	topics = append(topics, common.HexToHash("0x00"))
-	topics = append(topics, common.HexToHash("0x10"))
-	topics = append(topics, common.HexToHash("0x20"))
-	log := state.NewLog(address, topics, data, number)
-	return log
-}
-
-func makeHeader() *types.Header {
-	header := &types.Header{
-		ParentHash:  common.StringToHash("0x00"),
-		UncleHash:   common.StringToHash("0x00"),
-		Coinbase:    common.StringToAddress("0x00"),
-		Root:        common.StringToHash("0x00"),
-		TxHash:      common.StringToHash("0x00"),
-		ReceiptHash: common.StringToHash("0x00"),
-		// Bloom:
-		Difficulty: big.NewInt(88888888),
-		Number:     big.NewInt(16),
-		GasLimit:   big.NewInt(70000),
-		GasUsed:    big.NewInt(25000),
-		Time:       124356789,
-		Extra:      nil,
-		MixDigest:  common.StringToHash("0x00"),
-		Nonce:      [8]byte{0, 1, 2, 3, 4, 5, 6, 7},
-	}
-	return header
-}
-
-func makeBlock() *types.Block {
-	parentHash := common.HexToHash("0x01")
-	coinbase := common.HexToAddress("0x01")
-	root := common.HexToHash("0x01")
-	difficulty := common.Big1
-	nonce := uint64(1)
-	block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, nil)
-
-	txto := common.HexToAddress("0x02")
-	txamount := big.NewInt(1)
-	txgasAmount := big.NewInt(1)
-	txgasPrice := big.NewInt(1)
-	txdata := []byte{1, 2, 3}
-
-	tx := types.NewTransactionMessage(txto, txamount, txgasAmount, txgasPrice, txdata)
-	txs := make([]*types.Transaction, 1)
-	txs[0] = tx
-	block.SetTransactions(txs)
-
-	uncles := make([]*types.Header, 1)
-	uncles[0] = makeHeader()
-	block.SetUncles(uncles)
-
-	return block
-}
diff --git a/rpc/shared/types.go b/rpc/shared/types.go
index 6a29fa88e156f9222dd393b4382467f799e63b5a..7c4b04e83d04ef55ca5a3ce429663c8542307ee4 100644
--- a/rpc/shared/types.go
+++ b/rpc/shared/types.go
@@ -7,6 +7,21 @@ import (
 	"github.com/ethereum/go-ethereum/logger/glog"
 )
 
+// Ethereum RPC API interface
+type EthereumApi interface {
+	// API identifier
+	Name() string
+
+	// API version
+	ApiVersion() string
+
+	// Execute the given request and returns the response or an error
+	Execute(*Request) (interface{}, error)
+
+	// List of supported RCP methods this API provides
+	Methods() []string
+}
+
 // RPC request
 type Request struct {
 	Id      interface{}     `json:"id"`
@@ -42,6 +57,18 @@ type ErrorObject struct {
 	// Data    interface{} `json:"data"`
 }
 
+// Create RPC error response, this allows for custom error codes
+func NewRpcErrorResponse(id interface{}, jsonrpcver string, errCode int, err error) *interface{} {
+	var response interface{}
+
+	jsonerr := &ErrorObject{errCode, err.Error()}
+	response = ErrorResponse{Jsonrpc: jsonrpcver, Id: id, Error: jsonerr}
+
+	glog.V(logger.Detail).Infof("Generated error response: %s", response)
+	return &response
+}
+
+// Create RPC response
 func NewRpcResponse(id interface{}, jsonrpcver string, reply interface{}, err error) *interface{} {
 	var response interface{}
 
diff --git a/rpc/shared/utils.go b/rpc/shared/utils.go
new file mode 100644
index 0000000000000000000000000000000000000000..e5d6ad4177ddfc850015c2c39d7d7d52f5d76ecc
--- /dev/null
+++ b/rpc/shared/utils.go
@@ -0,0 +1,27 @@
+package shared
+
+import "strings"
+
+const (
+	AdminApiName    = "admin"
+	EthApiName      = "eth"
+	DbApiName       = "db"
+	DebugApiName    = "debug"
+	MergedApiName   = "merged"
+	MinerApiName    = "miner"
+	NetApiName      = "net"
+	ShhApiName      = "shh"
+	TxPoolApiName   = "txpool"
+	PersonalApiName = "personal"
+	Web3ApiName     = "web3"
+
+	JsonRpcVersion = "2.0"
+)
+
+var (
+	// All API's
+	AllApis = strings.Join([]string{
+		AdminApiName, DbApiName, EthApiName, DebugApiName, MinerApiName, NetApiName,
+		ShhApiName, TxPoolApiName, PersonalApiName, Web3ApiName,
+	}, ",")
+)
diff --git a/rpc/types.go b/rpc/types.go
deleted file mode 100644
index 1f49a3deac53ea67260acfae4de9e9ce8450e4bd..0000000000000000000000000000000000000000
--- a/rpc/types.go
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
-  This file is part of go-ethereum
-
-  go-ethereum is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  go-ethereum is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with go-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-package rpc
-
-import (
-	"encoding/binary"
-	"encoding/hex"
-	"encoding/json"
-	"fmt"
-	"math/big"
-	"strings"
-
-	"errors"
-	"net"
-	"net/http"
-	"time"
-
-	"io"
-
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/core/types"
-)
-
-type hexdata struct {
-	data  []byte
-	isNil bool
-}
-
-func (d *hexdata) String() string {
-	return "0x" + common.Bytes2Hex(d.data)
-}
-
-func (d *hexdata) MarshalJSON() ([]byte, error) {
-	if d.isNil {
-		return json.Marshal(nil)
-	}
-	return json.Marshal(d.String())
-}
-
-func newHexData(input interface{}) *hexdata {
-	d := new(hexdata)
-
-	if input == nil {
-		d.isNil = true
-		return d
-	}
-	switch input := input.(type) {
-	case []byte:
-		d.data = input
-	case common.Hash:
-		d.data = input.Bytes()
-	case *common.Hash:
-		if input == nil {
-			d.isNil = true
-		} else {
-			d.data = input.Bytes()
-		}
-	case common.Address:
-		d.data = input.Bytes()
-	case *common.Address:
-		if input == nil {
-			d.isNil = true
-		} else {
-			d.data = input.Bytes()
-		}
-	case types.Bloom:
-		d.data = input.Bytes()
-	case *types.Bloom:
-		if input == nil {
-			d.isNil = true
-		} else {
-			d.data = input.Bytes()
-		}
-	case *big.Int:
-		if input == nil {
-			d.isNil = true
-		} else {
-			d.data = input.Bytes()
-		}
-	case int64:
-		d.data = big.NewInt(input).Bytes()
-	case uint64:
-		buff := make([]byte, 8)
-		binary.BigEndian.PutUint64(buff, input)
-		d.data = buff
-	case int:
-		d.data = big.NewInt(int64(input)).Bytes()
-	case uint:
-		d.data = big.NewInt(int64(input)).Bytes()
-	case int8:
-		d.data = big.NewInt(int64(input)).Bytes()
-	case uint8:
-		d.data = big.NewInt(int64(input)).Bytes()
-	case int16:
-		d.data = big.NewInt(int64(input)).Bytes()
-	case uint16:
-		buff := make([]byte, 2)
-		binary.BigEndian.PutUint16(buff, input)
-		d.data = buff
-	case int32:
-		d.data = big.NewInt(int64(input)).Bytes()
-	case uint32:
-		buff := make([]byte, 4)
-		binary.BigEndian.PutUint32(buff, input)
-		d.data = buff
-	case string: // hexstring
-		// aaargh ffs TODO: avoid back-and-forth hex encodings where unneeded
-		bytes, err := hex.DecodeString(strings.TrimPrefix(input, "0x"))
-		if err != nil {
-			d.isNil = true
-		} else {
-			d.data = bytes
-		}
-	default:
-		d.isNil = true
-	}
-
-	return d
-}
-
-type hexnum struct {
-	data  []byte
-	isNil bool
-}
-
-func (d *hexnum) String() string {
-	// Get hex string from bytes
-	out := common.Bytes2Hex(d.data)
-	// Trim leading 0s
-	out = strings.TrimLeft(out, "0")
-	// Output "0x0" when value is 0
-	if len(out) == 0 {
-		out = "0"
-	}
-	return "0x" + out
-}
-
-func (d *hexnum) MarshalJSON() ([]byte, error) {
-	if d.isNil {
-		return json.Marshal(nil)
-	}
-	return json.Marshal(d.String())
-}
-
-func newHexNum(input interface{}) *hexnum {
-	d := new(hexnum)
-
-	d.data = newHexData(input).data
-
-	return d
-}
-
-type RpcConfig struct {
-	ListenAddress string
-	ListenPort    uint
-	CorsDomain    string
-}
-
-type InvalidTypeError struct {
-	method string
-	msg    string
-}
-
-func (e *InvalidTypeError) Error() string {
-	return fmt.Sprintf("invalid type on field %s: %s", e.method, e.msg)
-}
-
-func NewInvalidTypeError(method, msg string) *InvalidTypeError {
-	return &InvalidTypeError{
-		method: method,
-		msg:    msg,
-	}
-}
-
-type InsufficientParamsError struct {
-	have int
-	want int
-}
-
-func (e *InsufficientParamsError) Error() string {
-	return fmt.Sprintf("insufficient params, want %d have %d", e.want, e.have)
-}
-
-func NewInsufficientParamsError(have int, want int) *InsufficientParamsError {
-	return &InsufficientParamsError{
-		have: have,
-		want: want,
-	}
-}
-
-type NotImplementedError struct {
-	Method string
-}
-
-func (e *NotImplementedError) Error() string {
-	return fmt.Sprintf("%s method not implemented", e.Method)
-}
-
-func NewNotImplementedError(method string) *NotImplementedError {
-	return &NotImplementedError{
-		Method: method,
-	}
-}
-
-type NotAvailableError struct {
-	Method string
-	Reason string
-}
-
-func (e *NotAvailableError) Error() string {
-	return fmt.Sprintf("%s method not available: %s", e.Method, e.Reason)
-}
-
-func NewNotAvailableError(method string, reason string) *NotAvailableError {
-	return &NotAvailableError{
-		Method: method,
-		Reason: reason,
-	}
-}
-
-type DecodeParamError struct {
-	err string
-}
-
-func (e *DecodeParamError) Error() string {
-	return fmt.Sprintf("could not decode, %s", e.err)
-
-}
-
-func NewDecodeParamError(errstr string) error {
-	return &DecodeParamError{
-		err: errstr,
-	}
-}
-
-type ValidationError struct {
-	ParamName string
-	msg       string
-}
-
-func (e *ValidationError) Error() string {
-	return fmt.Sprintf("%s not valid, %s", e.ParamName, e.msg)
-}
-
-func NewValidationError(param string, msg string) error {
-	return &ValidationError{
-		ParamName: param,
-		msg:       msg,
-	}
-}
-
-type RpcRequest struct {
-	Id      interface{}     `json:"id"`
-	Jsonrpc string          `json:"jsonrpc"`
-	Method  string          `json:"method"`
-	Params  json.RawMessage `json:"params"`
-}
-
-type RpcSuccessResponse struct {
-	Id      interface{} `json:"id"`
-	Jsonrpc string      `json:"jsonrpc"`
-	Result  interface{} `json:"result"`
-}
-
-type RpcErrorResponse struct {
-	Id      interface{}     `json:"id"`
-	Jsonrpc string          `json:"jsonrpc"`
-	Error   *RpcErrorObject `json:"error"`
-}
-
-type RpcErrorObject struct {
-	Code    int    `json:"code"`
-	Message string `json:"message"`
-	// Data    interface{} `json:"data"`
-}
-
-type listenerHasStoppedError struct {
-	msg string
-}
-
-func (self listenerHasStoppedError) Error() string {
-	return self.msg
-}
-
-var listenerStoppedError = listenerHasStoppedError{"Listener stopped"}
-
-// When https://github.com/golang/go/issues/4674 is fixed this could be replaced
-type stoppableTCPListener struct {
-	*net.TCPListener
-	stop chan struct{} // closed when the listener must stop
-}
-
-// Wraps the default handler and checks if the RPC service was stopped. In that case it returns an
-// error indicating that the service was stopped. This will only happen for connections which are
-// kept open (HTTP keep-alive) when the RPC service was shutdown.
-func newStoppableHandler(h http.Handler, stop chan struct{}) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		select {
-		case <-stop:
-			w.Header().Set("Content-Type", "application/json")
-			jsonerr := &RpcErrorObject{-32603, "RPC service stopped"}
-			send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr})
-		default:
-			h.ServeHTTP(w, r)
-		}
-	})
-}
-
-// Stop the listener and all accepted and still active connections.
-func (self *stoppableTCPListener) Stop() {
-	close(self.stop)
-}
-
-func newStoppableTCPListener(addr string) (*stoppableTCPListener, error) {
-	wl, err := net.Listen("tcp", addr)
-	if err != nil {
-		return nil, err
-	}
-
-	if tcpl, ok := wl.(*net.TCPListener); ok {
-		stop := make(chan struct{})
-		l := &stoppableTCPListener{tcpl, stop}
-		return l, nil
-	}
-
-	return nil, errors.New("Unable to create TCP listener for RPC service")
-}
-
-func (self *stoppableTCPListener) Accept() (net.Conn, error) {
-	for {
-		self.SetDeadline(time.Now().Add(time.Duration(1 * time.Second)))
-		c, err := self.TCPListener.AcceptTCP()
-
-		select {
-		case <-self.stop:
-			if c != nil { // accept timeout
-				c.Close()
-			}
-			self.TCPListener.Close()
-			return nil, listenerStoppedError
-		default:
-		}
-
-		if err != nil {
-			if netErr, ok := err.(net.Error); ok && netErr.Timeout() && netErr.Temporary() {
-				continue // regular timeout
-			}
-		}
-
-		return &closableConnection{c, self.stop}, err
-	}
-}
-
-type closableConnection struct {
-	*net.TCPConn
-	closed chan struct{}
-}
-
-func (self *closableConnection) Read(b []byte) (n int, err error) {
-	select {
-	case <-self.closed:
-		self.TCPConn.Close()
-		return 0, io.EOF
-	default:
-		return self.TCPConn.Read(b)
-	}
-}
diff --git a/rpc/types_test.go b/rpc/types_test.go
deleted file mode 100644
index 9ef7b8d389d79e6224b9a0f3eec568c9d7026a1e..0000000000000000000000000000000000000000
--- a/rpc/types_test.go
+++ /dev/null
@@ -1,204 +0,0 @@
-package rpc
-
-import (
-	"bytes"
-	"encoding/json"
-	"math/big"
-	"testing"
-
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/core/types"
-)
-
-func TestInvalidTypeError(t *testing.T) {
-	err := NewInvalidTypeError("testField", "not string")
-	expected := "invalid type on field testField: not string"
-
-	if err.Error() != expected {
-		t.Error(err.Error())
-	}
-}
-
-func TestInsufficientParamsError(t *testing.T) {
-	err := NewInsufficientParamsError(0, 1)
-	expected := "insufficient params, want 1 have 0"
-
-	if err.Error() != expected {
-		t.Error(err.Error())
-	}
-}
-
-func TestNotImplementedError(t *testing.T) {
-	err := NewNotImplementedError("foo")
-	expected := "foo method not implemented"
-
-	if err.Error() != expected {
-		t.Error(err.Error())
-	}
-}
-
-func TestDecodeParamError(t *testing.T) {
-	err := NewDecodeParamError("foo")
-	expected := "could not decode, foo"
-
-	if err.Error() != expected {
-		t.Error(err.Error())
-	}
-}
-
-func TestValidationError(t *testing.T) {
-	err := NewValidationError("foo", "should be `bar`")
-	expected := "foo not valid, should be `bar`"
-
-	if err.Error() != expected {
-		t.Error(err.Error())
-	}
-}
-
-func TestHexdataMarshalNil(t *testing.T) {
-	hd := newHexData([]byte{})
-	hd.isNil = true
-	v, _ := json.Marshal(hd)
-	if string(v) != "null" {
-		t.Errorf("Expected null, got %s", v)
-	}
-}
-
-func TestHexnumMarshalNil(t *testing.T) {
-	hn := newHexNum([]byte{})
-	hn.isNil = true
-	v, _ := json.Marshal(hn)
-	if string(v) != "null" {
-		t.Errorf("Expected null, got %s", v)
-	}
-}
-
-func TestHexdataNil(t *testing.T) {
-	v := newHexData(nil)
-	if v.isNil != true {
-		t.Errorf("Expected isNil to be true, but is %v", v.isNil)
-	}
-}
-
-func TestHexdataPtrHash(t *testing.T) {
-	in := common.Hash{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}
-	v := newHexData(&in)
-	if bytes.Compare(in.Bytes(), v.data) != 0 {
-		t.Errorf("Got % x expected % x", in, v.data)
-	}
-}
-
-func TestHexdataPtrHashNil(t *testing.T) {
-	var in *common.Hash
-	in = nil
-	v := newHexData(in)
-	if !v.isNil {
-		t.Errorf("Expect isNil to be true, but is %v", v.isNil)
-	}
-}
-
-func TestHexdataPtrAddress(t *testing.T) {
-	in := common.Address{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
-	v := newHexData(&in)
-	if bytes.Compare(in.Bytes(), v.data) != 0 {
-		t.Errorf("Got % x expected % x", in, v.data)
-	}
-}
-
-func TestHexdataPtrAddressNil(t *testing.T) {
-	var in *common.Address
-	in = nil
-	v := newHexData(in)
-	if !v.isNil {
-		t.Errorf("Expect isNil to be true, but is %v", v.isNil)
-	}
-}
-
-func TestHexdataPtrBloom(t *testing.T) {
-	in := types.Bloom{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
-	v := newHexData(&in)
-	if bytes.Compare(in.Bytes(), v.data) != 0 {
-		t.Errorf("Got % x expected % x", in, v.data)
-	}
-}
-
-func TestHexdataPtrBloomNil(t *testing.T) {
-	var in *types.Bloom
-	in = nil
-	v := newHexData(in)
-	if !v.isNil {
-		t.Errorf("Expect isNil to be true, but is %v", v.isNil)
-	}
-}
-
-func TestHexdataBigintNil(t *testing.T) {
-	var in *big.Int
-	in = nil
-	v := newHexData(in)
-	if !v.isNil {
-		t.Errorf("Expect isNil to be true, but is %v", v.isNil)
-	}
-}
-
-func TestHexdataUint(t *testing.T) {
-	var in = uint(16)
-	var expected = []byte{0x10}
-	v := newHexData(in)
-	if bytes.Compare(expected, v.data) != 0 {
-		t.Errorf("Expected % x got % x", expected, v.data)
-	}
-}
-
-func TestHexdataInt8(t *testing.T) {
-	var in = int8(16)
-	var expected = []byte{0x10}
-	v := newHexData(in)
-	if bytes.Compare(expected, v.data) != 0 {
-		t.Errorf("Expected % x got % x", expected, v.data)
-	}
-}
-
-func TestHexdataUint8(t *testing.T) {
-	var in = uint8(16)
-	var expected = []byte{0x10}
-	v := newHexData(in)
-	if bytes.Compare(expected, v.data) != 0 {
-		t.Errorf("Expected % x got % x", expected, v.data)
-	}
-}
-
-func TestHexdataInt16(t *testing.T) {
-	var in = int16(16)
-	var expected = []byte{0x10}
-	v := newHexData(in)
-	if bytes.Compare(expected, v.data) != 0 {
-		t.Errorf("Expected % x got % x", expected, v.data)
-	}
-}
-
-func TestHexdataUint16(t *testing.T) {
-	var in = uint16(16)
-	var expected = []byte{0x0, 0x10}
-	v := newHexData(in)
-	if bytes.Compare(expected, v.data) != 0 {
-		t.Errorf("Expected % x got % x", expected, v.data)
-	}
-}
-
-func TestHexdataInt32(t *testing.T) {
-	var in = int32(16)
-	var expected = []byte{0x10}
-	v := newHexData(in)
-	if bytes.Compare(expected, v.data) != 0 {
-		t.Errorf("Expected % x got % x", expected, v.data)
-	}
-}
-
-func TestHexdataUint32(t *testing.T) {
-	var in = uint32(16)
-	var expected = []byte{0x0, 0x0, 0x0, 0x10}
-	v := newHexData(in)
-	if bytes.Compare(expected, v.data) != 0 {
-		t.Errorf("Expected % x got % x", expected, v.data)
-	}
-}