Browse Source

added admin API

Bas van Kervel 10 years ago
parent
commit
cc9ae39933
14 changed files with 613 additions and 203 deletions
  1. 228 0
      rpc/api/admin.go
  2. 107 0
      rpc/api/admin_args.go
  3. 67 0
      rpc/api/admin_js.go
  4. 2 5
      rpc/api/api.go
  5. 19 19
      rpc/api/debug.go
  6. 90 90
      rpc/api/eth.go
  7. 15 15
      rpc/api/eth_args.go
  8. 7 7
      rpc/api/mergedapi.go
  9. 23 23
      rpc/api/miner.go
  10. 15 15
      rpc/api/net.go
  11. 7 0
      rpc/api/net_js.go
  12. 15 15
      rpc/api/personal.go
  13. 6 2
      rpc/api/utils.go
  14. 12 12
      rpc/api/web3.go

+ 228 - 0
rpc/api/admin.go

@@ -0,0 +1,228 @@
+package api
+
+import (
+	"fmt"
+	"io"
+	"os"
+
+	"github.com/ethereum/go-ethereum/core"
+	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/eth"
+	"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/shared"
+	"github.com/ethereum/go-ethereum/xeth"
+)
+
+const (
+	AdminVersion    = "1.0.0"
+	importBatchSize = 2500
+)
+
+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,
+		"admin_exportChain": (*adminApi).ExportChain,
+		"admin_importChain": (*adminApi).ImportChain,
+		"admin_verbosity":   (*adminApi).Verbosity,
+		"admin_syncStatus":  (*adminApi).SyncStatus,
+		"admin_setSolc":     (*adminApi).SetSolc,
+	}
+)
+
+// admin callback handler
+type adminhandler func(*adminApi, *shared.Request) (interface{}, error)
+
+// admin api provider
+type adminApi struct {
+	xeth     *xeth.XEth
+	ethereum *eth.Ethereum
+	methods  map[string]adminhandler
+	codec    codec.ApiCoder
+}
+
+// create a new admin api instance
+func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *adminApi {
+	return &adminApi{
+		xeth:     xeth,
+		ethereum: ethereum,
+		methods:  AdminMapping,
+		codec:    coder.New(nil),
+	}
+}
+
+// collection with supported methods
+func (self *adminApi) 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 *adminApi) 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 *adminApi) Name() string {
+	return AdminApiName
+}
+
+func (self *adminApi) AddPeer(req *shared.Request) (interface{}, error) {
+	args := new(AddPeerArgs)
+	if err := self.codec.Decode(req.Params, &args); err != nil {
+		return nil, shared.NewDecodeParamError(err.Error())
+	}
+
+	err := self.ethereum.AddPeer(args.Url)
+	if err == nil {
+		return true, nil
+	}
+	return false, err
+}
+
+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
+}
+
+func hasAllBlocks(chain *core.ChainManager, bs []*types.Block) bool {
+	for _, b := range bs {
+		if !chain.HasBlock(b.Hash()) {
+			return false
+		}
+	}
+	return true
+}
+
+func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) {
+	args := new(ImportExportChainArgs)
+	if err := self.codec.Decode(req.Params, &args); err != nil {
+		return nil, shared.NewDecodeParamError(err.Error())
+	}
+
+	fh, err := os.Open(args.Filename)
+	if err != nil {
+		return false, err
+	}
+	defer fh.Close()
+	stream := rlp.NewStream(fh, 0)
+
+	// Run actual the import.
+	blocks := make(types.Blocks, importBatchSize)
+	n := 0
+	for batch := 0; ; batch++ {
+
+		i := 0
+		for ; i < importBatchSize; i++ {
+			var b types.Block
+			if err := stream.Decode(&b); err == io.EOF {
+				break
+			} else if err != nil {
+				return false, fmt.Errorf("at block %d: %v", n, err)
+			}
+			blocks[i] = &b
+			n++
+		}
+		if i == 0 {
+			break
+		}
+		// Import the batch.
+		if hasAllBlocks(self.ethereum.ChainManager(), blocks[:i]) {
+			continue
+		}
+		if _, err := self.ethereum.ChainManager().InsertChain(blocks[:i]); err != nil {
+			return false, fmt.Errorf("invalid block %d: %v", n, err)
+		}
+	}
+	return true, nil
+}
+
+func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) {
+	args := new(ImportExportChainArgs)
+	if err := self.codec.Decode(req.Params, &args); err != nil {
+		return nil, shared.NewDecodeParamError(err.Error())
+	}
+
+	fh, err := os.OpenFile(args.Filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
+	if err != nil {
+		return false, err
+	}
+	defer fh.Close()
+	if err := self.ethereum.ChainManager().Export(fh); err != nil {
+		return false, err
+	}
+
+	return true, nil
+}
+
+func (self *adminApi) Verbosity(req *shared.Request) (interface{}, error) {
+	args := new(VerbosityArgs)
+	if err := self.codec.Decode(req.Params, &args); err != nil {
+		return nil, shared.NewDecodeParamError(err.Error())
+	}
+
+	glog.SetV(args.Level)
+	return true, nil
+}
+
+func (self *adminApi) SyncStatus(req *shared.Request) (interface{}, error) {
+	pending, cached := self.ethereum.Downloader().Stats()
+	return map[string]interface{}{"available": pending, "waitingForImport": cached}, nil
+}
+
+func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) {
+	args := new(SetSolcArgs)
+	if err := self.codec.Decode(req.Params, &args); err != nil {
+		return nil, shared.NewDecodeParamError(err.Error())
+	}
+
+	solc, err := self.xeth.SetSolc(args.Path)
+	if err != nil {
+		return nil, err
+	}
+	return solc.Info(), nil
+}

+ 107 - 0
rpc/api/admin_args.go

@@ -0,0 +1,107 @@
+package api
+
+import (
+	"encoding/json"
+
+	"math/big"
+
+	"github.com/ethereum/go-ethereum/rpc/shared"
+)
+
+type AddPeerArgs struct {
+	Url string
+}
+
+func (args *AddPeerArgs) 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.NewDecodeParamError("Expected enode as argument")
+	}
+
+	urlstr, ok := obj[0].(string)
+	if !ok {
+		return shared.NewInvalidTypeError("url", "not a string")
+	}
+	args.Url = urlstr
+
+	return nil
+}
+
+type ImportExportChainArgs struct {
+	Filename string
+}
+
+func (args *ImportExportChainArgs) 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.NewDecodeParamError("Expected filename as argument")
+	}
+
+	filename, ok := obj[0].(string)
+	if !ok {
+		return shared.NewInvalidTypeError("filename", "not a string")
+	}
+	args.Filename = filename
+
+	return nil
+}
+
+type VerbosityArgs struct {
+	Level int
+}
+
+func (args *VerbosityArgs) 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.NewDecodeParamError("Expected enode as argument")
+	}
+
+	if levelint, ok := obj[0].(int); ok {
+		args.Level = levelint
+	} else if levelstr, ok := obj[0].(string); ok {
+		if !ok {
+			return shared.NewInvalidTypeError("level", "not a string")
+		}
+		level, success := new(big.Int).SetString(levelstr, 0)
+		if !success {
+			return shared.NewDecodeParamError("Unable to parse verbosity level")
+		}
+		args.Level = int(level.Int64())
+	}
+
+	return nil
+}
+
+type SetSolcArgs struct {
+	Path string
+}
+
+func (args *SetSolcArgs) 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.NewDecodeParamError("Expected path as argument")
+	}
+
+	if pathstr, ok := obj[0].(string); ok {
+		args.Path = pathstr
+		return nil
+	}
+
+	return shared.NewInvalidTypeError("path", "not a string")
+}

+ 67 - 0
rpc/api/admin_js.go

@@ -0,0 +1,67 @@
+package api
+
+const Admin_JS = `
+web3.extend({
+	property: 'admin',
+	methods:
+	[
+		new web3.extend.Method({
+			name: 'addPeer',
+			call: 'admin_addPeer',
+			params: 1,
+			inputFormatter: [web3.extend.utils.formatInputString],
+			outputFormatter: web3.extend.formatters.formatOutputBool
+		}),
+		new web3.extend.Method({
+			name: 'peers',
+			call: 'admin_peers',
+			params: 0,
+			inputFormatter: [],
+			outputFormatter: function(obj) { return obj; }
+		}),
+		new web3.extend.Method({
+			name: 'exportChain',
+			call: 'admin_exportChain',
+			params: 1,
+			inputFormatter: [web3.extend.utils.formatInputString],
+			outputFormatter: function(obj) { return obj; }
+		}),
+		new web3.extend.Method({
+			name: 'importChain',
+			call: 'admin_importChain',
+			params: 1,
+			inputFormatter: [web3.extend.utils.formatInputString],
+			outputFormatter: function(obj) { return obj; }
+		}),
+		new web3.extend.Method({
+			name: 'verbosity',
+			call: 'admin_verbosity',
+			params: 1,
+			inputFormatter: [web3.extend.utils.formatInputInt],
+			outputFormatter: web3.extend.formatters.formatOutputBool
+		}),
+		new web3.extend.Method({
+			name: 'syncStatus',
+			call: 'admin_syncStatus',
+			params: 1,
+			inputFormatter: [web3.extend.utils.formatInputInt],
+			outputFormatter: function(obj) { return obj; }
+		}),
+		new web3.extend.Method({
+			name: 'setSolc',
+			call: 'admin_setSolc',
+			params: 1,
+			inputFormatter: [web3.extend.utils.formatInputString],
+			outputFormatter: web3.extend.formatters.formatOutputString
+		})
+	],
+	properties:
+	[
+		new web3.extend.Property({
+			name: 'nodeInfo',
+			getter: 'admin_nodeInfo',
+			outputFormatter: web3.extend.formatters.formatOutputString
+		})
+	]
+});
+`

+ 2 - 5
rpc/api/api.go

@@ -7,6 +7,7 @@ import (
 )
 
 const (
+	AdminApiName    = "admin"
 	EthApiName      = "eth"
 	DebugApiName    = "debug"
 	MergedApiName   = "merged"
@@ -19,11 +20,7 @@ const (
 var (
 	// List with all API's which are offered over the IPC interface by default
 	DefaultIpcApis = strings.Join([]string{
-		EthApiName,
-		DebugApiName,
-		MinerApiName,
-		NetApiName,
-		PersonalApiName,
+		AdminApiName, EthApiName, DebugApiName, MinerApiName, NetApiName, PersonalApiName, Web3ApiName,
 	}, ",")
 )
 

+ 19 - 19
rpc/api/debug.go

@@ -20,20 +20,20 @@ const (
 var (
 	// mapping between methods and handlers
 	DebugMapping = map[string]debughandler{
-		"debug_dumpBlock":    (*DebugApi).DumpBlock,
-		"debug_getBlockRlp":  (*DebugApi).GetBlockRlp,
-		"debug_printBlock":   (*DebugApi).PrintBlock,
-		"debug_processBlock": (*DebugApi).ProcessBlock,
-		"debug_seedHash":     (*DebugApi).SeedHash,
-		"debug_setHead":      (*DebugApi).SetHead,
+		"debug_dumpBlock":    (*debugApi).DumpBlock,
+		"debug_getBlockRlp":  (*debugApi).GetBlockRlp,
+		"debug_printBlock":   (*debugApi).PrintBlock,
+		"debug_processBlock": (*debugApi).ProcessBlock,
+		"debug_seedHash":     (*debugApi).SeedHash,
+		"debug_setHead":      (*debugApi).SetHead,
 	}
 )
 
 // debug callback handler
-type debughandler func(*DebugApi, *shared.Request) (interface{}, error)
+type debughandler func(*debugApi, *shared.Request) (interface{}, error)
 
 // admin api provider
-type DebugApi struct {
+type debugApi struct {
 	xeth     *xeth.XEth
 	ethereum *eth.Ethereum
 	methods  map[string]debughandler
@@ -41,8 +41,8 @@ type DebugApi struct {
 }
 
 // create a new debug api instance
-func NewDebugApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *DebugApi {
-	return &DebugApi{
+func NewDebugApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *debugApi {
+	return &debugApi{
 		xeth:     xeth,
 		ethereum: ethereum,
 		methods:  DebugMapping,
@@ -51,7 +51,7 @@ func NewDebugApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *De
 }
 
 // collection with supported methods
-func (self *DebugApi) Methods() []string {
+func (self *debugApi) Methods() []string {
 	methods := make([]string, len(self.methods))
 	i := 0
 	for k := range self.methods {
@@ -62,7 +62,7 @@ func (self *DebugApi) Methods() []string {
 }
 
 // Execute given request
-func (self *DebugApi) Execute(req *shared.Request) (interface{}, error) {
+func (self *debugApi) Execute(req *shared.Request) (interface{}, error) {
 	if callback, ok := self.methods[req.Method]; ok {
 		return callback(self, req)
 	}
@@ -70,11 +70,11 @@ func (self *DebugApi) Execute(req *shared.Request) (interface{}, error) {
 	return nil, &shared.NotImplementedError{req.Method}
 }
 
-func (self *DebugApi) Name() string {
+func (self *debugApi) Name() string {
 	return DebugApiName
 }
 
-func (self *DebugApi) PrintBlock(req *shared.Request) (interface{}, error) {
+func (self *debugApi) PrintBlock(req *shared.Request) (interface{}, error) {
 	args := new(BlockNumArg)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -84,7 +84,7 @@ func (self *DebugApi) PrintBlock(req *shared.Request) (interface{}, error) {
 	return fmt.Sprintf("%s", block), nil
 }
 
-func (self *DebugApi) DumpBlock(req *shared.Request) (interface{}, error) {
+func (self *debugApi) DumpBlock(req *shared.Request) (interface{}, error) {
 	args := new(BlockNumArg)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -103,7 +103,7 @@ func (self *DebugApi) DumpBlock(req *shared.Request) (interface{}, error) {
 	return stateDb.Dump(), nil
 }
 
-func (self *DebugApi) GetBlockRlp(req *shared.Request) (interface{}, error) {
+func (self *debugApi) GetBlockRlp(req *shared.Request) (interface{}, error) {
 	args := new(BlockNumArg)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -117,7 +117,7 @@ func (self *DebugApi) GetBlockRlp(req *shared.Request) (interface{}, error) {
 	return fmt.Sprintf("%x", encoded), err
 }
 
-func (self *DebugApi) SetHead(req *shared.Request) (interface{}, error) {
+func (self *debugApi) SetHead(req *shared.Request) (interface{}, error) {
 	args := new(BlockNumArg)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -133,7 +133,7 @@ func (self *DebugApi) SetHead(req *shared.Request) (interface{}, error) {
 	return nil, nil
 }
 
-func (self *DebugApi) ProcessBlock(req *shared.Request) (interface{}, error) {
+func (self *debugApi) ProcessBlock(req *shared.Request) (interface{}, error) {
 	args := new(BlockNumArg)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -155,7 +155,7 @@ func (self *DebugApi) ProcessBlock(req *shared.Request) (interface{}, error) {
 	return false, err
 }
 
-func (self *DebugApi) SeedHash(req *shared.Request) (interface{}, error) {
+func (self *debugApi) SeedHash(req *shared.Request) (interface{}, error) {
 	args := new(BlockNumArg)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())

+ 90 - 90
rpc/api/eth.go

@@ -13,68 +13,68 @@ import (
 
 // eth api provider
 // See https://github.com/ethereum/wiki/wiki/JSON-RPC
-type EthApi struct {
+type ethApi struct {
 	xeth    *xeth.XEth
 	methods map[string]ethhandler
 	codec   codec.ApiCoder
 }
 
 // eth callback handler
-type ethhandler func(*EthApi, *shared.Request) (interface{}, error)
+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_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_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,
 	}
 )
 
-// create new EthApi instance
-func NewEthApi(xeth *xeth.XEth, codec codec.Codec) *EthApi {
-	return &EthApi{xeth, ethMapping, codec.New(nil)}
+// create new ethApi instance
+func NewEthApi(xeth *xeth.XEth, codec codec.Codec) *ethApi {
+	return &ethApi{xeth, ethMapping, codec.New(nil)}
 }
 
 // collection with supported methods
-func (self *EthApi) Methods() []string {
+func (self *ethApi) Methods() []string {
 	methods := make([]string, len(self.methods))
 	i := 0
 	for k := range self.methods {
@@ -85,7 +85,7 @@ func (self *EthApi) Methods() []string {
 }
 
 // Execute given request
-func (self *EthApi) Execute(req *shared.Request) (interface{}, error) {
+func (self *ethApi) Execute(req *shared.Request) (interface{}, error) {
 	if callback, ok := self.methods[req.Method]; ok {
 		return callback(self, req)
 	}
@@ -93,23 +93,23 @@ func (self *EthApi) Execute(req *shared.Request) (interface{}, error) {
 	return nil, shared.NewNotImplementedError(req.Method)
 }
 
-func (self *EthApi) Name() string {
+func (self *ethApi) Name() string {
 	return EthApiName
 }
 
-func (self *EthApi) Accounts(req *shared.Request) (interface{}, error) {
+func (self *ethApi) Accounts(req *shared.Request) (interface{}, error) {
 	return self.xeth.Accounts(), nil
 }
 
-func (self *EthApi) Hashrate(req *shared.Request) (interface{}, error) {
+func (self *ethApi) Hashrate(req *shared.Request) (interface{}, error) {
 	return newHexNum(self.xeth.HashRate()), nil
 }
 
-func (self *EthApi) BlockNumber(req *shared.Request) (interface{}, error) {
+func (self *ethApi) BlockNumber(req *shared.Request) (interface{}, error) {
 	return self.xeth.CurrentBlock().Number(), nil
 }
 
-func (self *EthApi) GetBalance(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetBalance(req *shared.Request) (interface{}, error) {
 	args := new(GetBalanceArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -118,23 +118,23 @@ func (self *EthApi) GetBalance(req *shared.Request) (interface{}, error) {
 	return self.xeth.AtStateNum(args.BlockNumber).BalanceAt(args.Address), nil
 }
 
-func (self *EthApi) ProtocolVersion(req *shared.Request) (interface{}, error) {
+func (self *ethApi) ProtocolVersion(req *shared.Request) (interface{}, error) {
 	return self.xeth.EthVersion(), nil
 }
 
-func (self *EthApi) Coinbase(req *shared.Request) (interface{}, error) {
+func (self *ethApi) Coinbase(req *shared.Request) (interface{}, error) {
 	return newHexData(self.xeth.Coinbase()), nil
 }
 
-func (self *EthApi) IsMining(req *shared.Request) (interface{}, error) {
+func (self *ethApi) IsMining(req *shared.Request) (interface{}, error) {
 	return self.xeth.IsMining(), nil
 }
 
-func (self *EthApi) GasPrice(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GasPrice(req *shared.Request) (interface{}, error) {
 	return newHexNum(xeth.DefaultGasPrice().Bytes()), nil
 }
 
-func (self *EthApi) GetStorage(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetStorage(req *shared.Request) (interface{}, error) {
 	args := new(GetStorageArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -143,7 +143,7 @@ func (self *EthApi) GetStorage(req *shared.Request) (interface{}, error) {
 	return self.xeth.AtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage(), nil
 }
 
-func (self *EthApi) GetStorageAt(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetStorageAt(req *shared.Request) (interface{}, error) {
 	args := new(GetStorageAtArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -152,7 +152,7 @@ func (self *EthApi) GetStorageAt(req *shared.Request) (interface{}, error) {
 	return self.xeth.AtStateNum(args.BlockNumber).StorageAt(args.Address, args.Key), nil
 }
 
-func (self *EthApi) GetTransactionCount(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetTransactionCount(req *shared.Request) (interface{}, error) {
 	args := new(GetTxCountArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -162,7 +162,7 @@ func (self *EthApi) GetTransactionCount(req *shared.Request) (interface{}, error
 	return newHexNum(big.NewInt(int64(count)).Bytes()), nil
 }
 
-func (self *EthApi) GetBlockTransactionCountByHash(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetBlockTransactionCountByHash(req *shared.Request) (interface{}, error) {
 	args := new(HashArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -176,7 +176,7 @@ func (self *EthApi) GetBlockTransactionCountByHash(req *shared.Request) (interfa
 	}
 }
 
-func (self *EthApi) GetBlockTransactionCountByNumber(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetBlockTransactionCountByNumber(req *shared.Request) (interface{}, error) {
 	args := new(BlockNumArg)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -190,7 +190,7 @@ func (self *EthApi) GetBlockTransactionCountByNumber(req *shared.Request) (inter
 	}
 }
 
-func (self *EthApi) GetUncleCountByBlockHash(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetUncleCountByBlockHash(req *shared.Request) (interface{}, error) {
 	args := new(HashArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -204,7 +204,7 @@ func (self *EthApi) GetUncleCountByBlockHash(req *shared.Request) (interface{},
 	return newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes()), nil
 }
 
-func (self *EthApi) GetUncleCountByBlockNumber(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetUncleCountByBlockNumber(req *shared.Request) (interface{}, error) {
 	args := new(BlockNumArg)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -218,7 +218,7 @@ func (self *EthApi) GetUncleCountByBlockNumber(req *shared.Request) (interface{}
 	return newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes()), nil
 }
 
-func (self *EthApi) GetData(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetData(req *shared.Request) (interface{}, error) {
 	args := new(GetDataArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -227,8 +227,8 @@ func (self *EthApi) GetData(req *shared.Request) (interface{}, error) {
 	return newHexData(v), nil
 }
 
-func (self *EthApi) Sign(req *shared.Request) (interface{}, error) {
-	args := new(NewSignArgs)
+func (self *ethApi) Sign(req *shared.Request) (interface{}, error) {
+	args := new(NewSigArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
 	}
@@ -239,7 +239,7 @@ func (self *EthApi) Sign(req *shared.Request) (interface{}, error) {
 	return v, nil
 }
 
-func (self *EthApi) SendTransaction(req *shared.Request) (interface{}, error) {
+func (self *ethApi) SendTransaction(req *shared.Request) (interface{}, error) {
 	args := new(NewTxArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -258,7 +258,7 @@ func (self *EthApi) SendTransaction(req *shared.Request) (interface{}, error) {
 	return v, nil
 }
 
-func (self *EthApi) EstimateGas(req *shared.Request) (interface{}, error) {
+func (self *ethApi) EstimateGas(req *shared.Request) (interface{}, error) {
 	_, gas, err := self.doCall(req.Params)
 	if err != nil {
 		return nil, err
@@ -272,7 +272,7 @@ func (self *EthApi) EstimateGas(req *shared.Request) (interface{}, error) {
 	}
 }
 
-func (self *EthApi) Call(req *shared.Request) (interface{}, error) {
+func (self *ethApi) Call(req *shared.Request) (interface{}, error) {
 	v, _, err := self.doCall(req.Params)
 	if err != nil {
 		return nil, err
@@ -286,11 +286,11 @@ func (self *EthApi) Call(req *shared.Request) (interface{}, error) {
 	}
 }
 
-func (self *EthApi) Flush(req *shared.Request) (interface{}, error) {
+func (self *ethApi) Flush(req *shared.Request) (interface{}, error) {
 	return nil, shared.NewNotImplementedError(req.Method)
 }
 
-func (self *EthApi) doCall(params json.RawMessage) (string, string, error) {
+func (self *ethApi) doCall(params json.RawMessage) (string, string, error) {
 	args := new(CallArgs)
 	if err := self.codec.Decode(params, &args); err != nil {
 		return "", "", err
@@ -299,7 +299,7 @@ func (self *EthApi) doCall(params json.RawMessage) (string, string, error) {
 	return self.xeth.AtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data)
 }
 
-func (self *EthApi) GetBlockByHash(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetBlockByHash(req *shared.Request) (interface{}, error) {
 	args := new(GetBlockByHashArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -309,7 +309,7 @@ func (self *EthApi) GetBlockByHash(req *shared.Request) (interface{}, error) {
 	return NewBlockRes(block, args.IncludeTxs), nil
 }
 
-func (self *EthApi) GetBlockByNumber(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetBlockByNumber(req *shared.Request) (interface{}, error) {
 	args := new(GetBlockByNumberArgs)
 	if err := json.Unmarshal(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -328,7 +328,7 @@ func (self *EthApi) GetBlockByNumber(req *shared.Request) (interface{}, error) {
 	return br, nil
 }
 
-func (self *EthApi) GetTransactionByHash(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetTransactionByHash(req *shared.Request) (interface{}, error) {
 	args := new(HashArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -348,7 +348,7 @@ func (self *EthApi) GetTransactionByHash(req *shared.Request) (interface{}, erro
 	return nil, nil
 }
 
-func (self *EthApi) GetTransactionByBlockHashAndIndex(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetTransactionByBlockHashAndIndex(req *shared.Request) (interface{}, error) {
 	args := new(HashIndexArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -367,7 +367,7 @@ func (self *EthApi) GetTransactionByBlockHashAndIndex(req *shared.Request) (inte
 	}
 }
 
-func (self *EthApi) GetTransactionByBlockNumberAndIndex(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetTransactionByBlockNumberAndIndex(req *shared.Request) (interface{}, error) {
 	args := new(BlockNumIndexArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -386,7 +386,7 @@ func (self *EthApi) GetTransactionByBlockNumberAndIndex(req *shared.Request) (in
 	return v.Transactions[args.Index], nil
 }
 
-func (self *EthApi) GetUncleByBlockHashAndIndex(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetUncleByBlockHashAndIndex(req *shared.Request) (interface{}, error) {
 	args := new(HashIndexArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -405,7 +405,7 @@ func (self *EthApi) GetUncleByBlockHashAndIndex(req *shared.Request) (interface{
 	return br.Uncles[args.Index], nil
 }
 
-func (self *EthApi) GetUncleByBlockNumberAndIndex(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetUncleByBlockNumberAndIndex(req *shared.Request) (interface{}, error) {
 	args := new(BlockNumIndexArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -425,7 +425,7 @@ func (self *EthApi) GetUncleByBlockNumberAndIndex(req *shared.Request) (interfac
 	}
 }
 
-func (self *EthApi) GetCompilers(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetCompilers(req *shared.Request) (interface{}, error) {
 	var lang string
 	if solc, _ := self.xeth.Solc(); solc != nil {
 		lang = "Solidity"
@@ -434,7 +434,7 @@ func (self *EthApi) GetCompilers(req *shared.Request) (interface{}, error) {
 	return c, nil
 }
 
-func (self *EthApi) CompileSolidity(req *shared.Request) (interface{}, error) {
+func (self *ethApi) CompileSolidity(req *shared.Request) (interface{}, error) {
 	solc, _ := self.xeth.Solc()
 	if solc == nil {
 		return nil, shared.NewNotAvailableError(req.Method, "solc (solidity compiler) not found")
@@ -452,7 +452,7 @@ func (self *EthApi) CompileSolidity(req *shared.Request) (interface{}, error) {
 	return contracts, nil
 }
 
-func (self *EthApi) NewFilter(req *shared.Request) (interface{}, error) {
+func (self *ethApi) NewFilter(req *shared.Request) (interface{}, error) {
 	args := new(BlockFilterArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -462,15 +462,15 @@ func (self *EthApi) NewFilter(req *shared.Request) (interface{}, error) {
 	return newHexNum(big.NewInt(int64(id)).Bytes()), nil
 }
 
-func (self *EthApi) NewBlockFilter(req *shared.Request) (interface{}, error) {
+func (self *ethApi) NewBlockFilter(req *shared.Request) (interface{}, error) {
 	return newHexNum(self.xeth.NewBlockFilter()), nil
 }
 
-func (self *EthApi) NewPendingTransactionFilter(req *shared.Request) (interface{}, error) {
+func (self *ethApi) NewPendingTransactionFilter(req *shared.Request) (interface{}, error) {
 	return newHexNum(self.xeth.NewTransactionFilter()), nil
 }
 
-func (self *EthApi) UninstallFilter(req *shared.Request) (interface{}, error) {
+func (self *ethApi) UninstallFilter(req *shared.Request) (interface{}, error) {
 	args := new(FilterIdArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -478,7 +478,7 @@ func (self *EthApi) UninstallFilter(req *shared.Request) (interface{}, error) {
 	return self.xeth.UninstallFilter(args.Id), nil
 }
 
-func (self *EthApi) GetFilterChanges(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetFilterChanges(req *shared.Request) (interface{}, error) {
 	args := new(FilterIdArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -496,7 +496,7 @@ func (self *EthApi) GetFilterChanges(req *shared.Request) (interface{}, error) {
 	}
 }
 
-func (self *EthApi) GetFilterLogs(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetFilterLogs(req *shared.Request) (interface{}, error) {
 	args := new(FilterIdArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -505,7 +505,7 @@ func (self *EthApi) GetFilterLogs(req *shared.Request) (interface{}, error) {
 	return NewLogsRes(self.xeth.Logs(args.Id)), nil
 }
 
-func (self *EthApi) GetLogs(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetLogs(req *shared.Request) (interface{}, error) {
 	args := new(BlockFilterArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -513,12 +513,12 @@ func (self *EthApi) GetLogs(req *shared.Request) (interface{}, error) {
 	return NewLogsRes(self.xeth.AllLogs(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)), nil
 }
 
-func (self *EthApi) GetWork(req *shared.Request) (interface{}, error) {
+func (self *ethApi) GetWork(req *shared.Request) (interface{}, error) {
 	self.xeth.SetMining(true, 0)
 	return self.xeth.RemoteMining().GetWork(), nil
 }
 
-func (self *EthApi) SubmitWork(req *shared.Request) (interface{}, error) {
+func (self *ethApi) SubmitWork(req *shared.Request) (interface{}, error) {
 	args := new(SubmitWorkArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())

+ 15 - 15
rpc/api/eth_args.go

@@ -226,19 +226,14 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
 	return nil
 }
 
-type NewSignArgs struct {
+type NewSigArgs struct {
 	From string
 	Data string
 }
 
-func (args *NewSignArgs) UnmarshalJSON(b []byte) (err error) {
-	var obj []json.RawMessage
-	var ext struct {
-		From string
-		Data string
-	}
+func (args *NewSigArgs) UnmarshalJSON(b []byte) (err error) {
+	var obj []interface{}
 
-	// Decode byte slice to array of RawMessages
 	if err := json.Unmarshal(b, &obj); err != nil {
 		return shared.NewDecodeParamError(err.Error())
 	}
@@ -248,21 +243,26 @@ func (args *NewSignArgs) UnmarshalJSON(b []byte) (err error) {
 		return shared.NewInsufficientParamsError(len(obj), 1)
 	}
 
-	// Decode 0th RawMessage to temporary struct
-	if err := json.Unmarshal(obj[0], &ext); err != nil {
-		return shared.NewDecodeParamError(err.Error())
+	from, ok := obj[0].(string)
+	if !ok {
+		return shared.NewInvalidTypeError("from", "not a string")
 	}
+	args.From = from
 
-	if len(ext.From) == 0 {
+	if len(args.From) == 0 {
 		return shared.NewValidationError("from", "is required")
 	}
 
-	if len(ext.Data) == 0 {
+	data, ok := obj[1].(string)
+	if !ok {
+		return shared.NewInvalidTypeError("data", "not a string")
+	}
+	args.Data = data
+
+	if len(args.Data) == 0 {
 		return shared.NewValidationError("data", "is required")
 	}
 
-	args.From = ext.From
-	args.Data = ext.Data
 	return nil
 }
 

+ 7 - 7
rpc/api/mergedapi.go

@@ -3,14 +3,14 @@ package api
 import "github.com/ethereum/go-ethereum/rpc/shared"
 
 // combines multiple API's
-type mergedApi struct {
+type MergedApi struct {
 	apis    []string
 	methods map[string]EthereumApi
 }
 
 // create new merged api instance
-func newMergedApi(apis ...EthereumApi) *mergedApi {
-	mergedApi := new(mergedApi)
+func newMergedApi(apis ...EthereumApi) *MergedApi {
+	mergedApi := new(MergedApi)
 	mergedApi.apis = make([]string, len(apis))
 	mergedApi.methods = make(map[string]EthereumApi)
 
@@ -24,7 +24,7 @@ func newMergedApi(apis ...EthereumApi) *mergedApi {
 }
 
 // Supported RPC methods
-func (self *mergedApi) Methods() []string {
+func (self *MergedApi) Methods() []string {
 	all := make([]string, len(self.methods))
 	for method, _ := range self.methods {
 		all = append(all, method)
@@ -33,7 +33,7 @@ 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) {
+func (self *MergedApi) Execute(req *shared.Request) (interface{}, error) {
 	if res, _ := self.handle(req); res != nil {
 		return res, nil
 	}
@@ -43,11 +43,11 @@ func (self *mergedApi) Execute(req *shared.Request) (interface{}, error) {
 	return nil, shared.NewNotImplementedError(req.Method)
 }
 
-func (self *mergedApi) Name() string {
+func (self *MergedApi) Name() string {
 	return MergedApiName
 }
 
-func (self *mergedApi) handle(req *shared.Request) (interface{}, error) {
+func (self *MergedApi) handle(req *shared.Request) (interface{}, error) {
 	if req.Method == "support_apis" { // provided API's
 		return self.apis, nil
 	}

+ 23 - 23
rpc/api/miner.go

@@ -15,30 +15,30 @@ const (
 var (
 	// mapping between methods and handlers
 	MinerMapping = map[string]minerhandler{
-		"miner_hashrate":     (*miner).Hashrate,
-		"miner_makeDAG":      (*miner).MakeDAG,
-		"miner_setExtra":     (*miner).SetExtra,
-		"miner_setGasPrice":  (*miner).SetGasPrice,
-		"miner_startAutoDAG": (*miner).StartAutoDAG,
-		"miner_start":        (*miner).StartMiner,
-		"miner_stopAutoDAG":  (*miner).StopAutoDAG,
-		"miner_stop":         (*miner).StopMiner,
+		"miner_hashrate":     (*minerApi).Hashrate,
+		"miner_makeDAG":      (*minerApi).MakeDAG,
+		"miner_setExtra":     (*minerApi).SetExtra,
+		"miner_setGasPrice":  (*minerApi).SetGasPrice,
+		"miner_startAutoDAG": (*minerApi).StartAutoDAG,
+		"miner_start":        (*minerApi).StartMiner,
+		"miner_stopAutoDAG":  (*minerApi).StopAutoDAG,
+		"miner_stop":         (*minerApi).StopMiner,
 	}
 )
 
 // miner callback handler
-type minerhandler func(*miner, *shared.Request) (interface{}, error)
+type minerhandler func(*minerApi, *shared.Request) (interface{}, error)
 
 // miner api provider
-type miner struct {
+type minerApi struct {
 	ethereum *eth.Ethereum
 	methods  map[string]minerhandler
 	codec    codec.ApiCoder
 }
 
 // create a new miner api instance
-func NewMinerApi(ethereum *eth.Ethereum, coder codec.Codec) *miner {
-	return &miner{
+func NewMinerApi(ethereum *eth.Ethereum, coder codec.Codec) *minerApi {
+	return &minerApi{
 		ethereum: ethereum,
 		methods:  MinerMapping,
 		codec:    coder.New(nil),
@@ -46,7 +46,7 @@ func NewMinerApi(ethereum *eth.Ethereum, coder codec.Codec) *miner {
 }
 
 // Execute given request
-func (self *miner) Execute(req *shared.Request) (interface{}, error) {
+func (self *minerApi) Execute(req *shared.Request) (interface{}, error) {
 	if callback, ok := self.methods[req.Method]; ok {
 		return callback(self, req)
 	}
@@ -55,7 +55,7 @@ func (self *miner) Execute(req *shared.Request) (interface{}, error) {
 }
 
 // collection with supported methods
-func (self *miner) Methods() []string {
+func (self *minerApi) Methods() []string {
 	methods := make([]string, len(self.methods))
 	i := 0
 	for k := range self.methods {
@@ -65,11 +65,11 @@ func (self *miner) Methods() []string {
 	return methods
 }
 
-func (self *miner) Name() string {
+func (self *minerApi) Name() string {
 	return MinerApiName
 }
 
-func (self *miner) StartMiner(req *shared.Request) (interface{}, error) {
+func (self *minerApi) StartMiner(req *shared.Request) (interface{}, error) {
 	args := new(StartMinerArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, err
@@ -87,16 +87,16 @@ func (self *miner) StartMiner(req *shared.Request) (interface{}, error) {
 	return false, err
 }
 
-func (self *miner) StopMiner(req *shared.Request) (interface{}, error) {
+func (self *minerApi) StopMiner(req *shared.Request) (interface{}, error) {
 	self.ethereum.StopMining()
 	return true, nil
 }
 
-func (self *miner) Hashrate(req *shared.Request) (interface{}, error) {
+func (self *minerApi) Hashrate(req *shared.Request) (interface{}, error) {
 	return self.ethereum.Miner().HashRate(), nil
 }
 
-func (self *miner) SetExtra(req *shared.Request) (interface{}, error) {
+func (self *minerApi) SetExtra(req *shared.Request) (interface{}, error) {
 	args := new(SetExtraArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, err
@@ -105,7 +105,7 @@ func (self *miner) SetExtra(req *shared.Request) (interface{}, error) {
 	return true, nil
 }
 
-func (self *miner) SetGasPrice(req *shared.Request) (interface{}, error) {
+func (self *minerApi) SetGasPrice(req *shared.Request) (interface{}, error) {
 	args := new(GasPriceArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return false, err
@@ -115,17 +115,17 @@ func (self *miner) SetGasPrice(req *shared.Request) (interface{}, error) {
 	return true, nil
 }
 
-func (self *miner) StartAutoDAG(req *shared.Request) (interface{}, error) {
+func (self *minerApi) StartAutoDAG(req *shared.Request) (interface{}, error) {
 	self.ethereum.StartAutoDAG()
 	return true, nil
 }
 
-func (self *miner) StopAutoDAG(req *shared.Request) (interface{}, error) {
+func (self *minerApi) StopAutoDAG(req *shared.Request) (interface{}, error) {
 	self.ethereum.StopAutoDAG()
 	return true, nil
 }
 
-func (self *miner) MakeDAG(req *shared.Request) (interface{}, error) {
+func (self *minerApi) MakeDAG(req *shared.Request) (interface{}, error) {
 	args := new(MakeDAGArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, err

+ 15 - 15
rpc/api/net.go

@@ -10,18 +10,18 @@ import (
 var (
 	// mapping between methods and handlers
 	netMapping = map[string]nethandler{
-		"net_id":        (*net).NetworkVersion,
-		"net_peerCount": (*net).PeerCount,
-		"net_listening": (*net).IsListening,
-		"net_peers":     (*net).Peers,
+		"net_id":        (*netApi).NetworkVersion,
+		"net_peerCount": (*netApi).PeerCount,
+		"net_listening": (*netApi).IsListening,
+		"net_peers":     (*netApi).Peers,
 	}
 )
 
 // net callback handler
-type nethandler func(*net, *shared.Request) (interface{}, error)
+type nethandler func(*netApi, *shared.Request) (interface{}, error)
 
 // net api provider
-type net struct {
+type netApi struct {
 	xeth     *xeth.XEth
 	ethereum *eth.Ethereum
 	methods  map[string]nethandler
@@ -29,8 +29,8 @@ type net struct {
 }
 
 // create a new net api instance
-func NewNetApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *net {
-	return &net{
+func NewNetApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *netApi {
+	return &netApi{
 		xeth:     xeth,
 		ethereum: eth,
 		methods:  netMapping,
@@ -39,7 +39,7 @@ func NewNetApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *net {
 }
 
 // collection with supported methods
-func (self *net) Methods() []string {
+func (self *netApi) Methods() []string {
 	methods := make([]string, len(self.methods))
 	i := 0
 	for k := range self.methods {
@@ -50,7 +50,7 @@ func (self *net) Methods() []string {
 }
 
 // Execute given request
-func (self *net) Execute(req *shared.Request) (interface{}, error) {
+func (self *netApi) Execute(req *shared.Request) (interface{}, error) {
 	if callback, ok := self.methods[req.Method]; ok {
 		return callback(self, req)
 	}
@@ -58,24 +58,24 @@ func (self *net) Execute(req *shared.Request) (interface{}, error) {
 	return nil, shared.NewNotImplementedError(req.Method)
 }
 
-func (self *net) Name() string {
+func (self *netApi) Name() string {
 	return NetApiName
 }
 
 // Network version
-func (self *net) NetworkVersion(req *shared.Request) (interface{}, error) {
+func (self *netApi) NetworkVersion(req *shared.Request) (interface{}, error) {
 	return self.xeth.NetworkVersion(), nil
 }
 
 // Number of connected peers
-func (self *net) PeerCount(req *shared.Request) (interface{}, error) {
+func (self *netApi) PeerCount(req *shared.Request) (interface{}, error) {
 	return self.xeth.PeerCount(), nil
 }
 
-func (self *net) IsListening(req *shared.Request) (interface{}, error) {
+func (self *netApi) IsListening(req *shared.Request) (interface{}, error) {
 	return self.xeth.IsListening(), nil
 }
 
-func (self *net) Peers(req *shared.Request) (interface{}, error) {
+func (self *netApi) Peers(req *shared.Request) (interface{}, error) {
 	return self.ethereum.PeersInfo(), nil
 }

+ 7 - 0
rpc/api/net_js.go

@@ -5,6 +5,13 @@ web3.extend({
 	property: 'network',
 	methods:
 	[
+		new web3.extend.Method({
+			name: 'addPeer',
+			call: 'net_addPeer',
+			params: 1,
+			inputFormatter: [web3.extend.utils.formatInputString],
+			outputFormatter: web3.extend.formatters.formatOutputBool
+		}),
 		new web3.extend.Method({
 			name: 'id',
 			call: 'net_id',

+ 15 - 15
rpc/api/personal.go

@@ -13,18 +13,18 @@ import (
 var (
 	// mapping between methods and handlers
 	personalMapping = map[string]personalhandler{
-		"personal_listAccounts":  (*personal).ListAccounts,
-		"personal_newAccount":    (*personal).NewAccount,
-		"personal_deleteAccount": (*personal).DeleteAccount,
-		"personal_unlockAccount": (*personal).UnlockAccount,
+		"personal_listAccounts":  (*personalApi).ListAccounts,
+		"personal_newAccount":    (*personalApi).NewAccount,
+		"personal_deleteAccount": (*personalApi).DeleteAccount,
+		"personal_unlockAccount": (*personalApi).UnlockAccount,
 	}
 )
 
 // net callback handler
-type personalhandler func(*personal, *shared.Request) (interface{}, error)
+type personalhandler func(*personalApi, *shared.Request) (interface{}, error)
 
 // net api provider
-type personal struct {
+type personalApi struct {
 	xeth     *xeth.XEth
 	ethereum *eth.Ethereum
 	methods  map[string]personalhandler
@@ -32,8 +32,8 @@ type personal struct {
 }
 
 // create a new net api instance
-func NewPersonal(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *personal {
-	return &personal{
+func NewPersonalApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *personalApi {
+	return &personalApi{
 		xeth:     xeth,
 		ethereum: eth,
 		methods:  personalMapping,
@@ -42,7 +42,7 @@ func NewPersonal(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *persona
 }
 
 // collection with supported methods
-func (self *personal) Methods() []string {
+func (self *personalApi) Methods() []string {
 	methods := make([]string, len(self.methods))
 	i := 0
 	for k := range self.methods {
@@ -53,7 +53,7 @@ func (self *personal) Methods() []string {
 }
 
 // Execute given request
-func (self *personal) Execute(req *shared.Request) (interface{}, error) {
+func (self *personalApi) Execute(req *shared.Request) (interface{}, error) {
 	if callback, ok := self.methods[req.Method]; ok {
 		return callback(self, req)
 	}
@@ -61,15 +61,15 @@ func (self *personal) Execute(req *shared.Request) (interface{}, error) {
 	return nil, shared.NewNotImplementedError(req.Method)
 }
 
-func (self *personal) Name() string {
+func (self *personalApi) Name() string {
 	return PersonalApiName
 }
 
-func (self *personal) ListAccounts(req *shared.Request) (interface{}, error) {
+func (self *personalApi) ListAccounts(req *shared.Request) (interface{}, error) {
 	return self.xeth.Accounts(), nil
 }
 
-func (self *personal) NewAccount(req *shared.Request) (interface{}, error) {
+func (self *personalApi) NewAccount(req *shared.Request) (interface{}, error) {
 	args := new(NewAccountArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -80,7 +80,7 @@ func (self *personal) NewAccount(req *shared.Request) (interface{}, error) {
 	return acc.Address.Hex(), err
 }
 
-func (self *personal) DeleteAccount(req *shared.Request) (interface{}, error) {
+func (self *personalApi) DeleteAccount(req *shared.Request) (interface{}, error) {
 	args := new(DeleteAccountArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())
@@ -95,7 +95,7 @@ func (self *personal) DeleteAccount(req *shared.Request) (interface{}, error) {
 	}
 }
 
-func (self *personal) UnlockAccount(req *shared.Request) (interface{}, error) {
+func (self *personalApi) UnlockAccount(req *shared.Request) (interface{}, error) {
 	args := new(UnlockAccountArgs)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, shared.NewDecodeParamError(err.Error())

+ 6 - 2
rpc/api/utils.go

@@ -21,6 +21,8 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.
 
 	for i, name := range names {
 		switch strings.ToLower(strings.TrimSpace(name)) {
+		case AdminApiName:
+			apis[i] = NewAdminApi(xeth, eth, codec)
 		case DebugApiName:
 			apis[i] = NewDebugApi(xeth, eth, codec)
 		case EthApiName:
@@ -30,9 +32,9 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.
 		case NetApiName:
 			apis[i] = NewNetApi(xeth, eth, codec)
 		case PersonalApiName:
-			apis[i] = NewPersonal(xeth, eth, codec)
+			apis[i] = NewPersonalApi(xeth, eth, codec)
 		case Web3ApiName:
-			apis[i] = NewWeb3(xeth, codec)
+			apis[i] = NewWeb3Api(xeth, codec)
 		default:
 			return nil, fmt.Errorf("Unknown API '%s'", name)
 		}
@@ -43,6 +45,8 @@ 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:
+		return Admin_JS
 	case DebugApiName:
 		return Debug_JS
 	case MinerApiName:

+ 12 - 12
rpc/api/web3.go

@@ -15,24 +15,24 @@ const (
 var (
 	// mapping between methods and handlers
 	Web3Mapping = map[string]web3handler{
-		"web3_sha3":          (*web3).Sha3,
-		"web3_clientVersion": (*web3).ClientVersion,
+		"web3_sha3":          (*web3Api).Sha3,
+		"web3_clientVersion": (*web3Api).ClientVersion,
 	}
 )
 
 // web3 callback handler
-type web3handler func(*web3, *shared.Request) (interface{}, error)
+type web3handler func(*web3Api, *shared.Request) (interface{}, error)
 
 // web3 api provider
-type web3 struct {
+type web3Api struct {
 	xeth    *xeth.XEth
 	methods map[string]web3handler
 	codec   codec.ApiCoder
 }
 
 // create a new web3 api instance
-func NewWeb3(xeth *xeth.XEth, coder codec.Codec) *web3 {
-	return &web3{
+func NewWeb3Api(xeth *xeth.XEth, coder codec.Codec) *web3Api {
+	return &web3Api{
 		xeth:    xeth,
 		methods: Web3Mapping,
 		codec:   coder.New(nil),
@@ -40,7 +40,7 @@ func NewWeb3(xeth *xeth.XEth, coder codec.Codec) *web3 {
 }
 
 // collection with supported methods
-func (self *web3) Methods() []string {
+func (self *web3Api) Methods() []string {
 	methods := make([]string, len(self.methods))
 	i := 0
 	for k := range self.methods {
@@ -51,7 +51,7 @@ func (self *web3) Methods() []string {
 }
 
 // Execute given request
-func (self *web3) Execute(req *shared.Request) (interface{}, error) {
+func (self *web3Api) Execute(req *shared.Request) (interface{}, error) {
 	if callback, ok := self.methods[req.Method]; ok {
 		return callback(self, req)
 	}
@@ -59,17 +59,17 @@ func (self *web3) Execute(req *shared.Request) (interface{}, error) {
 	return nil, &shared.NotImplementedError{req.Method}
 }
 
-func (self *web3) Name() string {
+func (self *web3Api) Name() string {
 	return Web3ApiName
 }
 
 // Version of the API this instance provides
-func (self *web3) Version() string {
+func (self *web3Api) Version() string {
 	return Web3Version
 }
 
 // Calculates the sha3 over req.Params.Data
-func (self *web3) Sha3(req *shared.Request) (interface{}, error) {
+func (self *web3Api) Sha3(req *shared.Request) (interface{}, error) {
 	args := new(Sha3Args)
 	if err := self.codec.Decode(req.Params, &args); err != nil {
 		return nil, err
@@ -79,6 +79,6 @@ func (self *web3) Sha3(req *shared.Request) (interface{}, error) {
 }
 
 // returns the xeth client vrsion
-func (self *web3) ClientVersion(req *shared.Request) (interface{}, error) {
+func (self *web3Api) ClientVersion(req *shared.Request) (interface{}, error) {
 	return self.xeth.ClientVersion(), nil
 }