added personal API

This commit is contained in:
Bas van Kervel 2015-06-09 10:59:44 +02:00 committed by Bas van Kervel
parent 09d0d55fc5
commit 08d72a9245
5 changed files with 259 additions and 9 deletions

@ -1,17 +1,30 @@
package api package api
import "github.com/ethereum/go-ethereum/rpc/shared" import (
"strings"
"github.com/ethereum/go-ethereum/rpc/shared"
)
const ( const (
// List with all API's which are offered over the IPC interface by default EthApiName = "eth"
DefaultIpcApis = "debug,eth,miner,net,web3" DebugApiName = "debug"
MergedApiName = "merged"
MinerApiName = "miner"
NetApiName = "net"
PersonalApiName = "personal"
Web3ApiName = "web3"
)
EthApiName = "eth" var (
DebugApiName = "debug" // List with all API's which are offered over the IPC interface by default
MergedApiName = "merged" DefaultIpcApis = strings.Join([]string{
MinerApiName = "miner" EthApiName,
NetApiName = "net" DebugApiName,
Web3ApiName = "web3" MinerApiName,
NetApiName,
PersonalApiName,
}, ",")
) )
// Ethereum RPC API interface // Ethereum RPC API interface

118
rpc/api/personal.go Normal file

@ -0,0 +1,118 @@
package api
import (
"time"
"github.com/ethereum/go-ethereum/common"
"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"
)
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,
}
)
// net callback handler
type personalhandler func(*personal, *shared.Request) (interface{}, error)
// net api provider
type personal struct {
xeth *xeth.XEth
ethereum *eth.Ethereum
methods map[string]personalhandler
codec codec.ApiCoder
}
// create a new net api instance
func NewPersonal(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *personal {
return &personal{
xeth: xeth,
ethereum: eth,
methods: personalMapping,
codec: coder.New(nil),
}
}
// collection with supported methods
func (self *personal) 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 *personal) Execute(req *shared.Request) (interface{}, error) {
if callback, ok := self.methods[req.Method]; ok {
return callback(self, req)
}
return nil, shared.NewNotImplementedError(req.Method)
}
func (self *personal) Name() string {
return PersonalApiName
}
func (self *personal) ListAccounts(req *shared.Request) (interface{}, error) {
return self.xeth.Accounts(), nil
}
func (self *personal) 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())
}
am := self.ethereum.AccountManager()
acc, err := am.NewAccount(args.Passphrase)
return acc.Address.Hex(), err
}
func (self *personal) 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())
}
addr := common.HexToAddress(args.Address)
am := self.ethereum.AccountManager()
if err := am.DeleteAccount(addr, args.Passphrase); err == nil {
return true, nil
} else {
return false, err
}
}
func (self *personal) 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())
}
var err error
am := self.ethereum.AccountManager()
addr := common.HexToAddress(args.Address)
if args.Duration == -1 {
err = am.Unlock(addr, args.Passphrase)
} else {
err = am.TimedUnlock(addr, args.Passphrase, time.Duration(args.Duration)*time.Second)
}
if err == nil {
return true, nil
}
return false, err
}

81
rpc/api/personal_args.go Normal file

@ -0,0 +1,81 @@
package api
import (
"encoding/json"
"github.com/ethereum/go-ethereum/rpc/shared"
)
type NewAccountArgs struct {
Passphrase string
}
func (args *NewAccountArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
passhrase, ok := obj[0].(string)
if !ok {
return shared.NewInvalidTypeError("passhrase", "not a string")
}
args.Passphrase = passhrase
return nil
}
type DeleteAccountArgs struct {
Address string
Passphrase string
}
func (args *DeleteAccountArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
addr, ok := obj[0].(string)
if !ok {
return shared.NewInvalidTypeError("address", "not a string")
}
args.Address = addr
passhrase, ok := obj[1].(string)
if !ok {
return shared.NewInvalidTypeError("passhrase", "not a string")
}
args.Passphrase = passhrase
return nil
}
type UnlockAccountArgs struct {
Address string
Passphrase string
Duration int
}
func (args *UnlockAccountArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
args.Duration = -1
addrstr, ok := obj[0].(string)
if !ok {
return shared.NewInvalidTypeError("address", "not a string")
}
args.Address = addrstr
passphrasestr, ok := obj[1].(string)
if !ok {
return shared.NewInvalidTypeError("passphrase", "not a string")
}
args.Passphrase = passphrasestr
return nil
}

34
rpc/api/personal_js.go Normal file

@ -0,0 +1,34 @@
package api
const Personal_JS = `
web3.extend({
property: 'personal',
methods:
[
new web3.extend.Method({
name: 'listAccounts',
call: 'personal_listAccounts',
params: 0,
inputFormatter: [],
outputFormatter: function(obj) { return obj; }
}),
new web3.extend.Method({
name: 'newAccount',
call: 'personal_newAccount',
params: 1,
inputFormatter: [web3.extend.formatters.formatInputString],
outputFormatter: web3.extend.formatters.formatOutputString
}),
new web3.extend.Method({
name: 'unlockAccount',
call: 'personal_unlockAccount',
params: 3,
inputFormatter: [web3.extend.formatters.formatInputString,web3.extend.formatters.formatInputString,web3.extend.formatters.formatInputInt],
outputFormatter: web3.extend.formatters.formatOutputBool
})
],
properties:
[
]
});
`

@ -29,6 +29,8 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.
apis[i] = NewMinerApi(eth, codec) apis[i] = NewMinerApi(eth, codec)
case NetApiName: case NetApiName:
apis[i] = NewNetApi(xeth, eth, codec) apis[i] = NewNetApi(xeth, eth, codec)
case PersonalApiName:
apis[i] = NewPersonal(xeth, eth, codec)
case Web3ApiName: case Web3ApiName:
apis[i] = NewWeb3(xeth, codec) apis[i] = NewWeb3(xeth, codec)
default: default:
@ -47,6 +49,8 @@ func Javascript(name string) string {
return Miner_JS return Miner_JS
case NetApiName: case NetApiName:
return Net_JS return Net_JS
case PersonalApiName:
return Personal_JS
} }
return "" return ""