diff --git a/client/client.go b/client/client.go
index 1c9c3502a5dc46d661c654414c917257cc143e05..81584b291dd296740a7d667e1c3d6f194cb71a15 100644
--- a/client/client.go
+++ b/client/client.go
@@ -18,19 +18,23 @@ package client
 
 import (
 	"fmt"
+	// "strings"
 
 	"github.com/tendermint/go-rpc/client"
 
+	log "github.com/eris-ltd/eris-logger"
+
 	acc "github.com/eris-ltd/eris-db/account"
 	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
+	core_types "github.com/eris-ltd/eris-db/core/types"
 	tendermint_client "github.com/eris-ltd/eris-db/rpc/tendermint/client"
 	tendermint_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types"
 	"github.com/eris-ltd/eris-db/txs"
-	core_types "github.com/eris-ltd/eris-db/core/types"
 )
 
 type NodeClient interface {
 	Broadcast(transaction txs.Tx) (*txs.Receipt, error)
+	DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error)
 
 	Status() (ChainId []byte, ValidatorPublicKey []byte, LatestBlockHash []byte,
 		LatestBlockHeight int, LatestBlockTime int64, err error)
@@ -38,11 +42,19 @@ type NodeClient interface {
 	QueryContract(callerAddress, calleeAddress, data []byte) (ret []byte, gasUsed int64, err error)
 	QueryContractCode(address, code, data []byte) (ret []byte, gasUsed int64, err error)
 
-	DumpStorage(address []byte) (storage *core_types.Storage, err error) 
+	DumpStorage(address []byte) (storage *core_types.Storage, err error)
 	GetName(name string) (owner []byte, data string, expirationBlock int, err error)
 	ListValidators() (blockHeight int, bondedValidators, unbondingValidators []consensus_types.Validator, err error)
 }
 
+type NodeWebsocketClient interface {
+	Subscribe(eventId string) error
+	Unsubscribe(eventId string) error
+
+	WaitForConfirmation(tx txs.Tx, chainId string, inputAddr []byte) (chan Confirmation, error)
+	Close()
+}
+
 // NOTE [ben] Compiler check to ensure ErisNodeClient successfully implements
 // eris-db/client.NodeClient
 var _ NodeClient = (*ErisNodeClient)(nil)
@@ -75,6 +87,38 @@ func (erisNodeClient *ErisNodeClient) Broadcast(tx txs.Tx) (*txs.Receipt, error)
 	return &receipt, nil
 }
 
+func (erisNodeClient *ErisNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error) {
+	var wsAddr string
+	// TODO: clean up this inherited mess on dealing with the address prefixes.
+	nodeAddr := erisNodeClient.broadcastRPC
+	// if strings.HasPrefix(nodeAddr, "http://") {
+	// 	wsAddr = strings.TrimPrefix(nodeAddr, "http://")
+	// }
+	// if strings.HasPrefix(nodeAddr, "tcp://") {
+	// 	wsAddr = strings.TrimPrefix(nodeAddr, "tcp://")
+	// }
+	// if strings.HasPrefix(nodeAddr, "unix://") {
+	// 	log.WithFields(log.Fields{
+	// 		"node address": nodeAddr,
+	// 	}).Error("Unable to subscribe to websocket from unix socket.")
+	// 	return nil, fmt.Errorf("Unable to construct websocket from unix socket: %s", nodeAddr)
+	// }
+	// wsAddr = "ws://" + wsAddr
+	wsAddr = nodeAddr
+	log.WithFields(log.Fields{
+		"websocket address": wsAddr,
+		"endpoint":          "/websocket",
+	}).Debug("Subscribing to websocket address")
+	wsClient := rpcclient.NewWSClient(wsAddr, "/websocket")
+	if _, err = wsClient.Start(); err != nil {
+		return nil, err
+	}
+	derivedErisNodeWebsocketClient := &ErisNodeWebsocketClient{
+		tendermintWebsocket: wsClient,
+	}
+	return derivedErisNodeWebsocketClient, nil
+}
+
 //------------------------------------------------------------------------------------
 // RPC requests other than transaction related
 
@@ -111,11 +155,11 @@ func (erisNodeClient *ErisNodeClient) ChainId() (ChainName, ChainId string, Gene
 	ChainId = chainIdResult.ChainId
 	GenesisHash = make([]byte, len(chainIdResult.GenesisHash))
 	copy(GenesisHash[:], chainIdResult.GenesisHash)
-	return 
+	return
 }
 
 // QueryContract executes the contract code at address with the given data
-// NOTE: there is no check on the caller; 
+// NOTE: there is no check on the caller;
 func (erisNodeClient *ErisNodeClient) QueryContract(callerAddress, calleeAddress, data []byte) (ret []byte, gasUsed int64, err error) {
 	client := rpcclient.NewClientJSONRPC(erisNodeClient.broadcastRPC)
 	callResult, err := tendermint_client.Call(client, callerAddress, calleeAddress, data)
@@ -207,6 +251,5 @@ func (erisNodeClient *ErisNodeClient) ListValidators() (blockHeight int,
 	blockHeight = validatorsResult.BlockHeight
 	bondedValidators = validatorsResult.BondedValidators
 	unbondingValidators = validatorsResult.UnbondingValidators
-	return 
+	return
 }
-
diff --git a/client/cmd/status.go b/client/cmd/status.go
index 376976300942b6af0d41fead8a5f1eb21ad052d0..5b29803d848fba681b028bcc0cae3cf969853968 100644
--- a/client/cmd/status.go
+++ b/client/cmd/status.go
@@ -23,8 +23,8 @@ import (
 )
 
 var StatusCmd = &cobra.Command{
-	Use:    "status",
-	Short:  "eris-client status returns the current status from a chain.",
+	Use:   "status",
+	Short: "eris-client status returns the current status from a chain.",
 	Long: `eris-client status returns the current status from a chain.
 `,
 	Run: func(cmd *cobra.Command, args []string) {
@@ -33,7 +33,7 @@ var StatusCmd = &cobra.Command{
 }
 
 func buildStatusCommand() {
-	addStatusPersistentFlags()	
+	addStatusPersistentFlags()
 }
 
 func addStatusPersistentFlags() {
diff --git a/client/cmd/transaction.go b/client/cmd/transaction.go
index 13076b0ec366a21a1e06082de52ff2dbf99f8e17..87a3e10c5ee99aeb84a97062280d98c4047d0016 100644
--- a/client/cmd/transaction.go
+++ b/client/cmd/transaction.go
@@ -149,7 +149,7 @@ func addTransactionPersistentFlags() {
 
 	// TransactionCmd.PersistentFlags().BoolVarP(&clientDo.SignFlag, "sign", "s", false, "sign the transaction using the eris-keys daemon")
 	TransactionCmd.PersistentFlags().BoolVarP(&clientDo.BroadcastFlag, "broadcast", "b", true, "broadcast the transaction to the blockchain")
-	TransactionCmd.PersistentFlags().BoolVarP(&clientDo.WaitFlag, "wait", "w", false, "wait for the transaction to be committed in a block")
+	TransactionCmd.PersistentFlags().BoolVarP(&clientDo.WaitFlag, "wait", "w", true, "wait for the transaction to be committed in a block")
 }
 
 //------------------------------------------------------------------------------
diff --git a/client/core/transaction_factory.go b/client/core/transaction_factory.go
index e631144c11bc36f70327b86488bd0ce66347564c..0385dccc65c77978e6cf6473b486df8962629370 100644
--- a/client/core/transaction_factory.go
+++ b/client/core/transaction_factory.go
@@ -20,8 +20,7 @@ import (
 	"encoding/hex"
 	"fmt"
 	"strconv"
-	// "strings"
-	// "time"
+
 	log "github.com/eris-ltd/eris-logger"
 
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
@@ -239,24 +238,24 @@ func Unbond(addrS, heightS string) (*txs.UnbondTx, error) {
 
 func Rebond(addrS, heightS string) (*txs.RebondTx, error) {
 	return nil, fmt.Errorf("Rebond Transaction formation to be implemented on 0.12.0")
-// 	if addrS == "" {
-// 		return nil, fmt.Errorf("Validator address must be given with --addr flag")
-// 	}
-
-// 	addrBytes, err := hex.DecodeString(addrS)
-// 	if err != nil {
-// 		return nil, fmt.Errorf("addr is bad hex: %v", err)
-// 	}
-
-// 	height, err := strconv.ParseInt(heightS, 10, 32)
-// 	if err != nil {
-// 		return nil, fmt.Errorf("height is misformatted: %v", err)
-// 	}
-
-// 	return &types.RebondTx{
-// 		Address: addrBytes,
-// 		Height:  int(height),
-// 	}, nil
+	// 	if addrS == "" {
+	// 		return nil, fmt.Errorf("Validator address must be given with --addr flag")
+	// 	}
+
+	// 	addrBytes, err := hex.DecodeString(addrS)
+	// 	if err != nil {
+	// 		return nil, fmt.Errorf("addr is bad hex: %v", err)
+	// 	}
+
+	// 	height, err := strconv.ParseInt(heightS, 10, 32)
+	// 	if err != nil {
+	// 		return nil, fmt.Errorf("height is misformatted: %v", err)
+	// 	}
+
+	// 	return &types.RebondTx{
+	// 		Address: addrBytes,
+	// 		Height:  int(height),
+	// 	}, nil
 }
 
 type TxResult struct {
@@ -274,9 +273,9 @@ type TxResult struct {
 
 // Preserve
 func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient keys.KeyClient, tx txs.Tx, sign, broadcast, wait bool) (txResult *TxResult, err error) {
-	// var inputAddr []byte
+	var inputAddr []byte
 	if sign {
-		_, tx, err = signTx(keyClient, chainID, tx)
+		inputAddr, tx, err = signTx(keyClient, chainID, tx)
 		if err != nil {
 			return nil, err
 		}
@@ -286,32 +285,46 @@ func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient ke
 	}
 
 	if broadcast {
-		// if wait {
-		// 	var ch chan Msg
-		// 	ch, err = subscribeAndWait(tx, chainID, nodeAddr, inputAddr)
-		// 	if err != nil {
-		// 		return nil, err
-		// 	} else {
-		// 		defer func() {
-		// 			if err != nil {
-		// 				// if broadcast threw an error, just return
-		// 				return
-		// 			}
-		// 			log.WithFields(log.Fields{
-		// 				"",
-		// 				}).Debug("Waiting for tx to be committed")
-		// 			msg := <-ch
-		// 			if msg.Error != nil {
-		// 				logger.Infof("Encountered error waiting for event: %v\n", msg.Error)
-		// 				err = msg.Error
-		// 			} else {
-		// 				txResult.BlockHash = msg.BlockHash
-		// 				txResult.Return = msg.Value
-		// 				txResult.Exception = msg.Exception
-		// 			}
-		// 		}()
-		// 	}
-		// }
+		if wait {
+			wsClient, err := nodeClient.DeriveWebsocketClient()
+			if err != nil {
+				return nil, err
+			}
+			var confirmationChannel chan client.Confirmation
+			confirmationChannel, err = wsClient.WaitForConfirmation(tx, chainID, inputAddr)
+			if err != nil {
+				return nil, err
+			} else {
+				defer func() {
+					if err != nil {
+						// if broadcast threw an error, just return
+						return
+					}
+					log.Debug("Waiting for transaction to be confirmed.")
+					confirmation := <-confirmationChannel
+					if confirmation.Error != nil {
+						log.Errorf("Encountered error waiting for event: %s\n", confirmation.Error)
+						err = confirmation.Error
+						return
+					}
+					if confirmation.Exception != nil {
+						log.Errorf("Encountered Exception from chain w: %s\n", confirmation.Error)
+						err = confirmation.Exception
+						return
+					}
+					txResult.BlockHash = confirmation.BlockHash
+					txResult.Exception = ""
+					eventDataTx, ok := confirmation.Event.(*txs.EventDataTx)
+					if !ok {
+						log.Errorf("Received wrong event type.")
+						err = fmt.Errorf("Received wrong event type.")
+						return
+					}
+					txResult.Return = eventDataTx.Return
+				}()
+			}
+		}
+
 		var receipt *txs.Receipt
 		receipt, err = nodeClient.Broadcast(tx)
 		if err != nil {
@@ -331,102 +344,3 @@ func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient ke
 	}
 	return
 }
-
-//------------------------------------------------------------------------------------
-// wait for events
-
-type Msg struct {
-	BlockHash []byte
-	Value     []byte
-	Exception string
-	Error     error
-}
-
-// func subscribeAndWait(tx txs.Tx, chainID, nodeAddr string, inputAddr []byte) (chan Msg, error) {
-// 	// subscribe to event and wait for tx to be committed
-// 	var wsAddr string
-// 	if strings.HasPrefix(nodeAddr, "http://") {
-// 		wsAddr = strings.TrimPrefix(nodeAddr, "http://")
-// 	}
-// 	if strings.HasPrefix(nodeAddr, "tcp://") {
-// 		wsAddr = strings.TrimPrefix(nodeAddr, "tcp://")
-// 	}
-// 	if strings.HasPrefix(nodeAddr, "unix://") {
-// 		log.WithFields(log.Fields{
-// 			"node address": nodeAddr,
-// 			}).Warn("Unable to subscribe to websocket from unix socket.")
-// 		return nil, fmt.Errorf("Unable to subscribe to websocket from unix socket: %s", nodeAddr)
-// 	}
-// 	wsAddr = "ws://" + wsAddr
-// 	log.WithFields(log.Fields{
-// 		"websocket address": wsAddr,
-// 		"endpoint": "/websocket",
-// 		}).Debug("Subscribing to websocket address")
-// 	wsClient := rpcclient.NewWSClient(wsAddr, "/websocket")
-// 	wsClient.Start()
-// 	eid := txs.EventStringAccInput(inputAddr)
-// 	if err := wsClient.Subscribe(eid); err != nil {
-// 		return nil, fmt.Errorf("Error subscribing to AccInput event: %v", err)
-// 	}
-// 	if err := wsClient.Subscribe(txs.EventStringNewBlock()); err != nil {
-// 		return nil, fmt.Errorf("Error subscribing to NewBlock event: %v", err)
-// 	}
-
-// 	resultChan := make(chan Msg, 1)
-
-// 	var latestBlockHash []byte
-
-// 	// Read message
-// 	go func() {
-// 		for {
-// 			result := <-wsClient.EventsCh
-// 			// if its a block, remember the block hash
-// 			blockData, ok := result.Data.(txs.EventDataNewBlock)
-// 			if ok {
-// 				log.Infoln(blockData.Block)
-// 				latestBlockHash = blockData.Block.Hash()
-// 				continue
-// 			}
-
-// 			// we don't accept events unless they came after a new block (ie. in)
-// 			if latestBlockHash == nil {
-// 				continue
-// 			}
-
-// 			if result.Event != eid {
-// 				logger.Debugf("received unsolicited event! Got %s, expected %s\n", result.Event, eid)
-// 				continue
-// 			}
-
-// 			data, ok := result.Data.(types.EventDataTx)
-// 			if !ok {
-// 				resultChan <- Msg{Error: fmt.Errorf("response error: expected result.Data to be *types.EventDataTx")}
-// 				return
-// 			}
-
-// 			if !bytes.Equal(types.TxID(chainID, data.Tx), types.TxID(chainID, tx)) {
-// 				logger.Debugf("Received event for same input from another transaction: %X\n", types.TxID(chainID, data.Tx))
-// 				continue
-// 			}
-
-// 			if data.Exception != "" {
-// 				resultChan <- Msg{BlockHash: latestBlockHash, Value: data.Return, Exception: data.Exception}
-// 				return
-// 			}
-
-// 			// GOOD!
-// 			resultChan <- Msg{BlockHash: latestBlockHash, Value: data.Return}
-// 			return
-// 		}
-// 	}()
-
-// 	// txs should take no more than 10 seconds
-// 	timeoutTicker := time.Tick(time.Duration(MaxCommitWaitTimeSeconds) * time.Second)
-
-// 	go func() {
-// 		<-timeoutTicker
-// 		resultChan <- Msg{Error: fmt.Errorf("timed out waiting for event")}
-// 		return
-// 	}()
-// 	return resultChan, nil
-// }
diff --git a/client/core/transaction_factory_util.go b/client/core/transaction_factory_util.go
index 01c2382618907eaaf8e7aa25903167ca0923d08b..3ad64a6ba36ad88ad5c11b6a0d70584285239095 100644
--- a/client/core/transaction_factory_util.go
+++ b/client/core/transaction_factory_util.go
@@ -120,10 +120,9 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 		}
 		pubKeyBytes, err2 = keyClient.PublicKey(addressBytes)
 		if err2 != nil {
-			err = fmt.Errorf("Failed to fetch pubkey for address (%s): %v", addr, err)
+			err = fmt.Errorf("Failed to fetch pubkey for address (%s): %v", addr, err2)
 			return
 		}
-
 	}
 
 	if len(pubKeyBytes) == 0 {
diff --git a/client/methods/status.go b/client/methods/status.go
index 2954fd1d283c759e24eabf66ed6499fd74ff397f..ba2470e7645ba0759445daed1042211c8f184401 100644
--- a/client/methods/status.go
+++ b/client/methods/status.go
@@ -25,7 +25,7 @@ import (
 	"github.com/eris-ltd/eris-db/definitions"
 )
 
-func Status(do *definitions.ClientDo)  {
+func Status(do *definitions.ClientDo) {
 	erisNodeClient := client.NewErisNodeClient(do.NodeAddrFlag)
 	genesisHash, validatorPublicKey, latestBlockHash, latestBlockHeight, latestBlockTime, err := erisNodeClient.Status()
 	if err != nil {
@@ -40,14 +40,14 @@ func Status(do *definitions.ClientDo)  {
 	}
 
 	log.WithFields(log.Fields{
-		"chain": do.NodeAddrFlag,
-		"genesisHash": fmt.Sprintf("%X", genesisHash),
-		"chainName": chainName,
-		"chainId": chainId,
-		"genesisHash from chainId":fmt.Sprintf("%X", genesisHashfromChainId),
-		"validator public key": fmt.Sprintf("%X", validatorPublicKey),
-		"latest block hash": fmt.Sprintf("%X", latestBlockHash),
-		"latest block height": latestBlockHeight,
-		"latest block time": latestBlockTime,
+		"chain":                    do.NodeAddrFlag,
+		"genesisHash":              fmt.Sprintf("%X", genesisHash),
+		"chainName":                chainName,
+		"chainId":                  chainId,
+		"genesisHash from chainId": fmt.Sprintf("%X", genesisHashfromChainId),
+		"validator public key":     fmt.Sprintf("%X", validatorPublicKey),
+		"latest block hash":        fmt.Sprintf("%X", latestBlockHash),
+		"latest block height":      latestBlockHeight,
+		"latest block time":        latestBlockTime,
 	}).Info("status")
 }
diff --git a/client/mock/client_mock.go b/client/mock/client_mock.go
index 24a94e93a37e04b6a84cf1a59c34963fc0fcc998..12cdd76cf9b15f9575898224889a1528eb8a58b7 100644
--- a/client/mock/client_mock.go
+++ b/client/mock/client_mock.go
@@ -19,10 +19,10 @@ package mock
 import (
 	"github.com/tendermint/go-crypto"
 
-	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
-	core_types "github.com/eris-ltd/eris-db/core/types"
 	acc "github.com/eris-ltd/eris-db/account"
 	. "github.com/eris-ltd/eris-db/client"
+	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
+	core_types "github.com/eris-ltd/eris-db/core/types"
 	"github.com/eris-ltd/eris-db/txs"
 )
 
@@ -50,6 +50,10 @@ func (mock *MockNodeClient) Broadcast(transaction txs.Tx) (*txs.Receipt, error)
 	return txReceipt, nil
 }
 
+func (mock *MockNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error) {
+	return nil, nil
+}
+
 func (mock *MockNodeClient) GetAccount(address []byte) (*acc.Account, error) {
 	// make zero account
 	var zero [32]byte
@@ -88,7 +92,6 @@ func (mock *MockNodeClient) Status() (ChainId []byte,
 	return
 }
 
-
 // QueryContract executes the contract code at address with the given data
 func (mock *MockNodeClient) QueryContract(callerAddress, calleeAddress, data []byte) (ret []byte, gasUsed int64, err error) {
 	// return zero
@@ -103,7 +106,6 @@ func (mock *MockNodeClient) QueryContractCode(address, code, data []byte) (ret [
 	return ret, 0, nil
 }
 
-
 func (mock *MockNodeClient) DumpStorage(address []byte) (storage *core_types.Storage, err error) {
 	return nil, nil
 }
@@ -112,6 +114,6 @@ func (mock *MockNodeClient) GetName(name string) (owner []byte, data string, exp
 	return nil, "", 0, nil
 }
 
-func (mock *MockNodeClient) ListValidators() (blockHeight int, bondedValidators, unbondingValidators []consensus_types.Validator, err error){
+func (mock *MockNodeClient) ListValidators() (blockHeight int, bondedValidators, unbondingValidators []consensus_types.Validator, err error) {
 	return 0, nil, nil, nil
 }
diff --git a/client/websocket_client.go b/client/websocket_client.go
new file mode 100644
index 0000000000000000000000000000000000000000..42f1bf37d384f999cb5d913cbf741124e71f1736
--- /dev/null
+++ b/client/websocket_client.go
@@ -0,0 +1,208 @@
+// Copyright 2015, 2016 Eris Industries (UK) Ltd.
+// This file is part of Eris-RT
+
+// Eris-RT 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.
+
+// Eris-RT 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 Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+
+package client
+
+import (
+	"bytes"
+	"fmt"
+	"time"
+
+	"github.com/tendermint/go-rpc/client"
+	"github.com/tendermint/go-wire"
+
+	log "github.com/eris-ltd/eris-logger"
+
+	ctypes "github.com/eris-ltd/eris-db/rpc/tendermint/core/types"
+	"github.com/eris-ltd/eris-db/txs"
+)
+
+const (
+	MaxCommitWaitTimeSeconds = 10
+)
+
+type Confirmation struct {
+	BlockHash []byte
+	Event     txs.EventData
+	Exception error
+	Error     error
+}
+
+// NOTE [ben] Compiler check to ensure ErisNodeClient successfully implements
+// eris-db/client.NodeClient
+var _ NodeWebsocketClient = (*ErisNodeWebsocketClient)(nil)
+
+type ErisNodeWebsocketClient struct {
+	// TODO: assert no memory leak on closing with open websocket
+	tendermintWebsocket *rpcclient.WSClient
+}
+
+// Subscribe to an eventid
+func (erisNodeWebsocketClient *ErisNodeWebsocketClient) Subscribe(eventid string) error {
+	// TODO we can in the background listen to the subscription id and remember it to ease unsubscribing later.
+	return erisNodeWebsocketClient.tendermintWebsocket.Subscribe(eventid)
+}
+
+// Unsubscribe from an eventid
+func (erisNodeWebsocketClient *ErisNodeWebsocketClient) Unsubscribe(subscriptionId string) error {
+	return erisNodeWebsocketClient.tendermintWebsocket.Unsubscribe(subscriptionId)
+}
+
+// Returns a channel that will receive a confirmation with a result or the exception that
+// has been confirmed; or an error is returned and the confirmation channel is nil.
+func (erisNodeWebsocketClient *ErisNodeWebsocketClient) WaitForConfirmation(tx txs.Tx, chainId string, inputAddr []byte) (chan Confirmation, error) {
+	// check no errors are reported on the websocket
+	if err := erisNodeWebsocketClient.assertNoErrors(); err != nil {
+		return nil, err
+	}
+
+	// Setup the confirmation channel to be returned
+	confirmationChannel := make(chan Confirmation, 1)
+	var latestBlockHash []byte
+
+	eid := txs.EventStringAccInput(inputAddr)
+	if err := erisNodeWebsocketClient.tendermintWebsocket.Subscribe(eid); err != nil {
+		return nil, fmt.Errorf("Error subscribing to AccInput event (%s): %v", eid, err)
+	}
+	if err := erisNodeWebsocketClient.tendermintWebsocket.Subscribe(txs.EventStringNewBlock()); err != nil {
+		return nil, fmt.Errorf("Error subscribing to NewBlock event: %v", err)
+	}
+	// Read the incoming events
+	go func() {
+		var err error
+		for {
+			resultBytes := <-erisNodeWebsocketClient.tendermintWebsocket.ResultsCh
+			result := new(ctypes.ErisDBResult)
+			if wire.ReadJSONPtr(result, resultBytes, &err); err != nil {
+				// keep calm and carry on
+				log.Errorf("[eris-client] Failed to unmarshal json bytes for websocket event: %s", err)
+				continue
+			}
+
+			subscription, ok := (*result).(*ctypes.ResultSubscribe)
+			if ok {
+				// Received confirmation of subscription to event streams
+				// TODO: collect subscription IDs, push into channel and on completion
+				// unsubscribe
+				log.Infof("[eris-client] recceived confirmation for event (%s) with subscription id (%s).",
+					subscription.Event, subscription.SubscriptionId)
+				continue
+			}
+
+			event, ok := (*result).(*ctypes.ResultEvent)
+			if !ok {
+				// keep calm and carry on
+				log.Warnf("[eris-client] Failed to cast to ResultEvent for websocket event: %s", *result)
+				continue
+			}
+
+			blockData, ok := event.Data.(txs.EventDataNewBlock)
+			if ok {
+				latestBlockHash = blockData.Block.Hash()
+				log.WithFields(log.Fields{
+					"new block":   blockData.Block,
+					"latest hash": latestBlockHash,
+				}).Debug("Registered new block")
+				continue
+			}
+
+			// we don't accept events unless they came after a new block (ie. in)
+			if latestBlockHash == nil {
+				log.Infof("[eris-client] no first block has been registered, so ignoring event: %s", event.Event)
+				continue
+			}
+
+			if event.Event != eid {
+				log.Warnf("[eris-client] received unsolicited event! Got %s, expected %s\n", event.Event, eid)
+				continue
+			}
+
+			data, ok := event.Data.(txs.EventDataTx)
+			if !ok {
+				// We are on the lookout for EventDataTx
+				confirmationChannel <- Confirmation{
+					BlockHash: latestBlockHash,
+					Event:     nil,
+					Exception: fmt.Errorf("response error: expected result.Data to be *types.EventDataTx"),
+					Error:     nil,
+				}
+				return
+			}
+
+			if !bytes.Equal(txs.TxHash(chainId, data.Tx), txs.TxHash(chainId, tx)) {
+				log.WithFields(log.Fields{
+					// TODO: consider re-implementing TxID again, or other more clear debug
+					"received transaction event": txs.TxHash(chainId, data.Tx),
+				}).Debug("Received different event")
+				continue
+			}
+
+			if data.Exception != "" {
+				confirmationChannel <- Confirmation{
+					BlockHash: latestBlockHash,
+					Event:     &data,
+					Exception: fmt.Errorf("Transaction confirmed with exception:", data.Exception),
+					Error:     nil,
+				}
+				return
+			}
+			// success, return the full event and blockhash and exit go-routine
+			confirmationChannel <- Confirmation{
+				BlockHash: latestBlockHash,
+				Event:     &data,
+				Exception: nil,
+				Error:     nil,
+			}
+			return
+		}
+
+	}()
+
+	// TODO: [ben] this is a draft implementation as resources on time.After can not be
+	// recovered before the timeout.  Close-down timeout at success properly.
+	timeout := time.After(time.Duration(MaxCommitWaitTimeSeconds) * time.Second)
+
+	go func() {
+		<-timeout
+		confirmationChannel <- Confirmation{
+			BlockHash: nil,
+			Event:     nil,
+			Exception: nil,
+			Error:     fmt.Errorf("timed out waiting for event"),
+		}
+		return
+	}()
+	return confirmationChannel, nil
+}
+
+func (erisNodeWebsocketClient *ErisNodeWebsocketClient) Close() {
+	if erisNodeWebsocketClient.tendermintWebsocket != nil {
+		erisNodeWebsocketClient.tendermintWebsocket.Stop()
+	}
+}
+
+func (erisNodeWebsocketClient *ErisNodeWebsocketClient) assertNoErrors() error {
+	if erisNodeWebsocketClient.tendermintWebsocket != nil {
+		select {
+		case err := <-erisNodeWebsocketClient.tendermintWebsocket.ErrorsCh:
+			return err
+		default:
+			return nil
+		}
+	} else {
+		return fmt.Errorf("Eris-client has no websocket initialised.")
+	}
+}
diff --git a/client/ws_client.go b/client/ws_client.go
index f2542c1a477eacb27d12f4e8f0f563c8e530b891..d60986b6f9a41575642dbf963aaceb281d52dfe5 100644
--- a/client/ws_client.go
+++ b/client/ws_client.go
@@ -1,6 +1,12 @@
 // Websocket client implementation. This will be used in tests.
 package client
 
+// NOTE: this websocket client acts on rpc/v0,
+// uses github.com/gorilla/websocket
+// and will be deprecated after 0.12
+// It is recommended to use the interfaces NodeClient
+// and NodeWebsocketClient.
+
 import (
 	"fmt"
 	"net/http"
diff --git a/keys/key_client.go b/keys/key_client.go
index 44a60f1f5c9f94f0839ec58eb8e115f2d9ec1d1e..994f5a67010943a3c7ac27416d192cb6cd2be067 100644
--- a/keys/key_client.go
+++ b/keys/key_client.go
@@ -68,7 +68,7 @@ func (erisKeys *ErisKeyClient) Sign(signBytesString string, signAddress []byte)
 // the eris-keys server.
 func (erisKeys *ErisKeyClient) PublicKey(address []byte) (publicKey []byte, err error) {
 	args := map[string]string{
-		"addr": string(address),
+		"addr": fmt.Sprintf("%X", address),
 	}
 	pubS, err := RequestResponse(erisKeys.rpcString, "pub", args)
 	if err != nil {