diff --git a/rpc/api/api.go b/rpc/api/api.go
index 067a4d4e8695b42a6e8533dcef54226c13c26a0c..d2c548ed1372b1434d00198075c43fd5c79b54e3 100644
--- a/rpc/api/api.go
+++ b/rpc/api/api.go
@@ -1,17 +1,30 @@
 package api
 
-import "github.com/ethereum/go-ethereum/rpc/shared"
+import (
+	"strings"
+
+	"github.com/ethereum/go-ethereum/rpc/shared"
+)
 
 const (
+	EthApiName      = "eth"
+	DebugApiName    = "debug"
+	MergedApiName   = "merged"
+	MinerApiName    = "miner"
+	NetApiName      = "net"
+	PersonalApiName = "personal"
+	Web3ApiName     = "web3"
+)
+
+var (
 	// List with all API's which are offered over the IPC interface by default
-	DefaultIpcApis = "debug,eth,miner,net,web3"
-
-	EthApiName    = "eth"
-	DebugApiName  = "debug"
-	MergedApiName = "merged"
-	MinerApiName  = "miner"
-	NetApiName    = "net"
-	Web3ApiName   = "web3"
+	DefaultIpcApis = strings.Join([]string{
+		EthApiName,
+		DebugApiName,
+		MinerApiName,
+		NetApiName,
+		PersonalApiName,
+	}, ",")
 )
 
 // Ethereum RPC API interface
diff --git a/rpc/api/personal.go b/rpc/api/personal.go
new file mode 100644
index 0000000000000000000000000000000000000000..d00363627aaa7eddd03cf41cfd3cf4e6ddd3e13e
--- /dev/null
+++ b/rpc/api/personal.go
@@ -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
+}
diff --git a/rpc/api/personal_args.go b/rpc/api/personal_args.go
new file mode 100644
index 0000000000000000000000000000000000000000..b41fc06e79d2a12915834cc5de7d31bbbecdee59
--- /dev/null
+++ b/rpc/api/personal_args.go
@@ -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
+}
diff --git a/rpc/api/personal_js.go b/rpc/api/personal_js.go
new file mode 100644
index 0000000000000000000000000000000000000000..7fd9a2deae482faccbc25dfb0cabfe2aa29a2a3e
--- /dev/null
+++ b/rpc/api/personal_js.go
@@ -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:
+	[
+	]
+});
+`
diff --git a/rpc/api/utils.go b/rpc/api/utils.go
index 6e6d5c7b0595000dcda1a50c2c141d05c2c42082..eae23d3510ccd669c0cd0f2ec4fa5d6f744871a1 100644
--- a/rpc/api/utils.go
+++ b/rpc/api/utils.go
@@ -29,6 +29,8 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.
 			apis[i] = NewMinerApi(eth, codec)
 		case NetApiName:
 			apis[i] = NewNetApi(xeth, eth, codec)
+		case PersonalApiName:
+			apis[i] = NewPersonal(xeth, eth, codec)
 		case Web3ApiName:
 			apis[i] = NewWeb3(xeth, codec)
 		default:
@@ -47,6 +49,8 @@ func Javascript(name string) string {
 		return Miner_JS
 	case NetApiName:
 		return Net_JS
+	case PersonalApiName:
+		return Personal_JS
 	}
 
 	return ""