diff --git a/definitions/client_do.go b/client/client_do.go
similarity index 93%
rename from definitions/client_do.go
rename to client/client_do.go
index fc0f25faf9bf4329996acd0360d9d303caf02ee0..4816cafd84eebc8c8107c5044745f7c94cb9a755 100644
--- a/definitions/client_do.go
+++ b/client/client_do.go
@@ -12,9 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package definitions
+package client
 
-type ClientDo struct {
+type Do struct {
 	// Persistent flags not reflected in the configuration files
 	// only set through command line flags or environment variables
 	Debug   bool // BURROW_DEBUG
@@ -25,7 +25,6 @@ type ClientDo struct {
 	NodeAddrFlag string
 	PubkeyFlag   string
 	AddrFlag     string
-	ChainidFlag  string
 
 	// signFlag      bool // TODO: remove; unsafe signing without monax-keys
 	BroadcastFlag bool
@@ -46,8 +45,8 @@ type ClientDo struct {
 	HeightFlag   string
 }
 
-func NewClientDo() *ClientDo {
-	clientDo := new(ClientDo)
+func NewClientDo() *Do {
+	clientDo := new(Do)
 	clientDo.Debug = false
 	clientDo.Verbose = false
 
@@ -55,7 +54,6 @@ func NewClientDo() *ClientDo {
 	clientDo.NodeAddrFlag = ""
 	clientDo.PubkeyFlag = ""
 	clientDo.AddrFlag = ""
-	clientDo.ChainidFlag = ""
 
 	// clientDo.signFlag = false
 	clientDo.BroadcastFlag = false
diff --git a/client/cmd/burrow-client.go b/client/cmd/burrow-client.go
index bb67c6ef4e92843c6d52dc557f0c5afa6a4452a8..23e10c4482490241ea70b4ce21f5b5c4bd1ae072 100644
--- a/client/cmd/burrow-client.go
+++ b/client/cmd/burrow-client.go
@@ -18,14 +18,13 @@ import (
 	"os"
 	"strconv"
 
-	"github.com/spf13/cobra"
-
-	"github.com/hyperledger/burrow/definitions"
+	"github.com/hyperledger/burrow/client"
 	"github.com/hyperledger/burrow/version"
+	"github.com/spf13/cobra"
 )
 
 // Global flags for persistent flags
-var clientDo *definitions.ClientDo
+var clientDo *client.Do
 
 var BurrowClientCmd = &cobra.Command{
 	Use:   "burrow-client",
@@ -47,8 +46,8 @@ func Execute() {
 }
 
 func InitBurrowClientInit() {
-	// initialise an empty ClientDo struct for command execution
-	clientDo = definitions.NewClientDo()
+	// initialise an empty Do struct for command execution
+	clientDo = client.NewClientDo()
 }
 
 func AddGlobalFlags() {
diff --git a/client/cmd/genesis.go b/client/cmd/genesis.go
index 3eb7f4621f6029aa7116369a6e228f29a55153c0..cb2d4fb19c32840851f8b770692e1213097bf672 100644
--- a/client/cmd/genesis.go
+++ b/client/cmd/genesis.go
@@ -17,7 +17,6 @@ package commands
 import (
 	"fmt"
 
-	"github.com/hyperledger/burrow/common/sanity"
 	"github.com/hyperledger/burrow/genesis"
 
 	"github.com/spf13/cobra"
@@ -38,7 +37,7 @@ var GenesisGenCmd = &cobra.Command{
 		// TODO refactor to not panic
 		genesisFile, err := genesis.GenerateKnown(args[0], AccountsPathFlag, ValidatorsPathFlag)
 		if err != nil {
-			sanity.PanicSanity(err)
+			panic(err)
 		}
 		fmt.Println(genesisFile) // may want to save somewhere instead
 	},
diff --git a/client/cmd/transaction.go b/client/cmd/transaction.go
index 21b97e65795a46ce4cb499e768529f15e7ca43a1..0bffd93875ac8f25a9c6aab49dfd719f508eb819 100644
--- a/client/cmd/transaction.go
+++ b/client/cmd/transaction.go
@@ -25,7 +25,7 @@ import (
 
 func buildTransactionCommand() *cobra.Command {
 	// Transaction command has subcommands send, name, call, bond,
-	// unbond, rebond, permissions. Dupeout transaction is not accessible through the command line.
+	// unbond, rebond, permissions.
 	transactionCmd := &cobra.Command{
 		Use:   "tx",
 		Short: "burrow-client tx formulates and signs a transaction to a chain",
@@ -145,7 +145,6 @@ func addTransactionPersistentFlags(transactionCmd *cobra.Command) {
 	transactionCmd.PersistentFlags().StringVarP(&clientDo.NodeAddrFlag, "node-addr", "", defaultNodeRpcAddress(), "set the burrow node rpc server address (default respects $BURROW_CLIENT_NODE_ADDRESS)")
 	transactionCmd.PersistentFlags().StringVarP(&clientDo.PubkeyFlag, "pubkey", "", defaultPublicKey(), "specify the public key to sign with (defaults to $BURROW_CLIENT_PUBLIC_KEY)")
 	transactionCmd.PersistentFlags().StringVarP(&clientDo.AddrFlag, "addr", "", defaultAddress(), "specify the account address (for which the public key can be found at monax-keys) (default respects $BURROW_CLIENT_ADDRESS)")
-	transactionCmd.PersistentFlags().StringVarP(&clientDo.ChainidFlag, "chain-id", "", defaultChainId(), "specify the chainID (default respects $CHAIN_ID)")
 	transactionCmd.PersistentFlags().StringVarP(&clientDo.NonceFlag, "nonce", "", "", "specify the nonce to use for the transaction (should equal the sender account's nonce + 1)")
 
 	// transactionCmd.PersistentFlags().BoolVarP(&clientDo.SignFlag, "sign", "s", false, "sign the transaction using the monax-keys daemon")
@@ -156,10 +155,6 @@ func addTransactionPersistentFlags(transactionCmd *cobra.Command) {
 //------------------------------------------------------------------------------
 // Defaults
 
-func defaultChainId() string {
-	return setDefaultString("CHAIN_ID", "")
-}
-
 func defaultKeyDaemonAddress() string {
 	return setDefaultString("BURROW_CLIENT_SIGN_ADDRESS", "http://127.0.0.1:4767")
 }
@@ -180,10 +175,6 @@ func defaultAddress() string {
 // Helper functions
 
 func assertParameters(cmd *cobra.Command, args []string) {
-	if clientDo.ChainidFlag == "" {
-		util.Fatalf(`Please provide a chain id either through the flag --chain-id or environment variable $CHAIN_ID.`)
-	}
-
 	if !strings.HasPrefix(clientDo.NodeAddrFlag, "tcp://") &&
 		!strings.HasPrefix(clientDo.NodeAddrFlag, "unix://") {
 		// TODO: [ben] go-rpc will deprecate reformatting; also it is bad practice to auto-correct for this;
diff --git a/client/methods/call.go b/client/methods/call.go
index 9df3a51ac5921fd43ae62d52e0fc3c52c499e783..84eed39085f35d9e4bb815d9fd521c8144b99e73 100644
--- a/client/methods/call.go
+++ b/client/methods/call.go
@@ -19,16 +19,15 @@ import (
 
 	"github.com/hyperledger/burrow/client"
 	"github.com/hyperledger/burrow/client/rpc"
-	"github.com/hyperledger/burrow/definitions"
 	"github.com/hyperledger/burrow/keys"
 )
 
-func Call(do *definitions.ClientDo) error {
+func Call(do *client.Do) error {
 	// construct two clients to call out to keys server and
 	// blockchain node.
 	logger, err := loggerFromClientDo(do, "Call")
 	if err != nil {
-		return fmt.Errorf("Could not generate logging config from ClientDo: %s", err)
+		return fmt.Errorf("Could not generate logging config from Do: %s", err)
 	}
 	burrowKeyClient := keys.NewBurrowKeyClient(do.SignAddrFlag, logger)
 	burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger)
@@ -39,10 +38,14 @@ func Call(do *definitions.ClientDo) error {
 	if err != nil {
 		return fmt.Errorf("Failed on forming Call Transaction: %s", err)
 	}
+	_, chainID, _, err := burrowNodeClient.ChainId()
+	if err != nil {
+		return err
+	}
 	// TODO: [ben] we carry over the sign bool, but always set it to true,
 	// as we move away from and deprecate the api that allows sending unsigned
 	// transactions and relying on (our) receiving node to sign it.
-	txResult, err := rpc.SignAndBroadcast(do.ChainidFlag, burrowNodeClient, burrowKeyClient,
+	txResult, err := rpc.SignAndBroadcast(chainID, burrowNodeClient, burrowKeyClient,
 		callTransaction, true, do.BroadcastFlag, do.WaitFlag)
 
 	if err != nil {
diff --git a/client/methods/helpers.go b/client/methods/helpers.go
index 2e8bc6fcaddb11eac66c55f8992039a9beec8feb..6cdb8b3aedaca504d7ec803c250f9e1265686e0a 100644
--- a/client/methods/helpers.go
+++ b/client/methods/helpers.go
@@ -15,10 +15,10 @@
 package methods
 
 import (
+	"github.com/hyperledger/burrow/client"
 	"github.com/hyperledger/burrow/client/rpc"
-	"github.com/hyperledger/burrow/core"
-	"github.com/hyperledger/burrow/definitions"
 	"github.com/hyperledger/burrow/logging"
+	"github.com/hyperledger/burrow/logging/config"
 	"github.com/hyperledger/burrow/logging/lifecycle"
 	logging_types "github.com/hyperledger/burrow/logging/types"
 )
@@ -45,17 +45,12 @@ func unpackSignAndBroadcast(result *rpc.TxResult, logger logging_types.InfoTrace
 	logging.InfoMsg(logger, "SignAndBroadcast result")
 }
 
-func loggerFromClientDo(do *definitions.ClientDo, scope string) (logging_types.InfoTraceLogger, error) {
-	lc, err := core.LoadLoggingConfigFromClientDo(do)
-	if err != nil {
-		return nil, err
-	}
-	logger, err := lifecycle.NewLoggerFromLoggingConfig(lc)
+func loggerFromClientDo(do *client.Do, scope string) (logging_types.InfoTraceLogger, error) {
+	logger, err := lifecycle.NewLoggerFromLoggingConfig(config.DefaultClientLoggingConfig())
 	if err != nil {
 		return nil, err
 	}
 	logger = logging.WithScope(logger, scope)
 	lifecycle.CaptureStdlibLogOutput(logger)
-	lifecycle.CaptureTendermintLog15Output(logger)
 	return logger, nil
 }
diff --git a/client/methods/send.go b/client/methods/send.go
index 9437a9dfd754826699e2e7c06606da1f4b0f1e2b..9527bc75a5112f446222aaa541088d38d9ebacb6 100644
--- a/client/methods/send.go
+++ b/client/methods/send.go
@@ -19,16 +19,15 @@ import (
 
 	"github.com/hyperledger/burrow/client"
 	"github.com/hyperledger/burrow/client/rpc"
-	"github.com/hyperledger/burrow/definitions"
 	"github.com/hyperledger/burrow/keys"
 )
 
-func Send(do *definitions.ClientDo) error {
+func Send(do *client.Do) error {
 	// construct two clients to call out to keys server and
 	// blockchain node.
 	logger, err := loggerFromClientDo(do, "Send")
 	if err != nil {
-		return fmt.Errorf("Could not generate logging config from ClientDo: %s", err)
+		return fmt.Errorf("Could not generate logging config from Do: %s", err)
 	}
 	burrowKeyClient := keys.NewBurrowKeyClient(do.SignAddrFlag, logger)
 	burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger)
@@ -38,10 +37,14 @@ func Send(do *definitions.ClientDo) error {
 	if err != nil {
 		fmt.Errorf("Failed on forming Send Transaction: %s", err)
 	}
+	_, chainID, _, err := burrowNodeClient.ChainId()
+	if err != nil {
+		return err
+	}
 	// TODO: [ben] we carry over the sign bool, but always set it to true,
 	// as we move away from and deprecate the api that allows sending unsigned
 	// transactions and relying on (our) receiving node to sign it.
-	txResult, err := rpc.SignAndBroadcast(do.ChainidFlag, burrowNodeClient, burrowKeyClient,
+	txResult, err := rpc.SignAndBroadcast(chainID, burrowNodeClient, burrowKeyClient,
 		sendTransaction, true, do.BroadcastFlag, do.WaitFlag)
 	if err != nil {
 		return fmt.Errorf("Failed on signing (and broadcasting) transaction: %s", err)
diff --git a/client/methods/status.go b/client/methods/status.go
index d14c3290b6367baab80ef5bdc3df3cbb098dcd8b..14a8be609eb100ca2cdecc3652f6af840e45cd6d 100644
--- a/client/methods/status.go
+++ b/client/methods/status.go
@@ -18,13 +18,12 @@ import (
 	"fmt"
 
 	"github.com/hyperledger/burrow/client"
-	"github.com/hyperledger/burrow/definitions"
 )
 
-func Status(do *definitions.ClientDo) error {
+func Status(do *client.Do) error {
 	logger, err := loggerFromClientDo(do, "Status")
 	if err != nil {
-		return fmt.Errorf("Could not generate logging config from ClientDo: %s", err)
+		return fmt.Errorf("Could not generate logging config from Do: %s", err)
 	}
 	burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger)
 	genesisHash, validatorPublicKey, latestBlockHash, latestBlockHeight, latestBlockTime, err := burrowNodeClient.Status()
diff --git a/client/mock/client_mock.go b/client/mock/client_mock.go
index c6a0d12b8bb5f95a9bf98e1c1b5c28a1c53e02af..1289774c9aa2bafc5191d09e467ae800ffb1e28c 100644
--- a/client/mock/client_mock.go
+++ b/client/mock/client_mock.go
@@ -15,26 +15,24 @@
 package mock
 
 import (
-	"github.com/tendermint/go-crypto"
-
-	acc "github.com/hyperledger/burrow/account"
+	acm "github.com/hyperledger/burrow/account"
 	. "github.com/hyperledger/burrow/client"
-	consensus_types "github.com/hyperledger/burrow/consensus/types"
-	core_types "github.com/hyperledger/burrow/core/types"
 	"github.com/hyperledger/burrow/logging/loggers"
 	logging_types "github.com/hyperledger/burrow/logging/types"
+	"github.com/hyperledger/burrow/rpc"
 	"github.com/hyperledger/burrow/txs"
+	"github.com/tendermint/go-crypto"
 )
 
 var _ NodeClient = (*MockNodeClient)(nil)
 
 type MockNodeClient struct {
-	accounts map[string]*acc.Account
+	accounts map[string]*acm.ConcreteAccount
 }
 
 func NewMockNodeClient() *MockNodeClient {
 	return &MockNodeClient{
-		accounts: make(map[string]*acc.Account),
+		accounts: make(map[string]*acm.ConcreteAccount),
 	}
 }
 
@@ -42,8 +40,7 @@ func (mock *MockNodeClient) Broadcast(transaction txs.Tx) (*txs.Receipt, error)
 	// make zero transaction receipt
 	txReceipt := &txs.Receipt{
 		TxHash:          make([]byte, 20),
-		CreatesContract: 0,
-		ContractAddr:    make([]byte, 20),
+		CreatesContract: false,
 	}
 	return txReceipt, nil
 }
@@ -52,68 +49,60 @@ func (mock *MockNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketC
 	return nil, nil
 }
 
-func (mock *MockNodeClient) GetAccount(address []byte) (*acc.Account, error) {
+func (mock *MockNodeClient) GetAccount(address acm.Address) (acm.Account, error) {
 	// make zero account
-	var zero [32]byte
-	copyAddressBytes := make([]byte, len(address))
-	copy(copyAddressBytes, address)
-	account := &acc.Account{
-		Address:     copyAddressBytes,
-		PubKey:      crypto.PubKey(crypto.PubKeyEd25519(zero)),
-		Sequence:    0,
-		Balance:     0,
+	return acm.ConcreteAccount{
+		Address:     address,
+		PublicKey:   acm.PublicKeyFromPubKey(crypto.PubKeyEd25519{}.Wrap()),
 		Code:        make([]byte, 0),
 		StorageRoot: make([]byte, 0),
-	}
-	return account, nil
+	}.Account(), nil
 }
 
-func (mock *MockNodeClient) MockAddAccount(account *acc.Account) {
+func (mock *MockNodeClient) MockAddAccount(account *acm.ConcreteAccount) {
 	addressString := string(account.Address[:])
 	mock.accounts[addressString] = account.Copy()
 }
 
-func (mock *MockNodeClient) Status() (ChainId []byte,
-	ValidatorPublicKey []byte, LatestBlockHash []byte,
-	BlockHeight int, LatestBlockTime int64, err error) {
-	// make zero account
-	var zero [32]byte
-	ed25519 := crypto.PubKeyEd25519(zero)
-	pub := crypto.PubKey(ed25519)
-
+func (mock *MockNodeClient) Status() (ChainId []byte, ValidatorPublicKey []byte, LatestBlockHash []byte,
+	BlockHeight uint64, LatestBlockTime int64, err error) {
 	// fill return values
 	ChainId = make([]byte, 64)
 	LatestBlockHash = make([]byte, 64)
-	ValidatorPublicKey = pub.Bytes()
+	ValidatorPublicKey = crypto.PubKeyEd25519{}.Wrap().Bytes()
 	BlockHeight = 0
 	LatestBlockTime = 0
 	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) {
+func (mock *MockNodeClient) QueryContract(callerAddress, calleeAddress acm.Address,
+	data []byte) (ret []byte, gasUsed uint64, err error) {
+
 	// return zero
 	ret = make([]byte, 0)
-	return ret, 0, nil
+	return
 }
 
 // QueryContractCode executes the contract code at address with the given data but with provided code
-func (mock *MockNodeClient) QueryContractCode(address, code, data []byte) (ret []byte, gasUsed int64, err error) {
+func (mock *MockNodeClient) QueryContractCode(address acm.Address, code,
+	data []byte) (ret []byte, gasUsed uint64, err error) {
 	// return zero
 	ret = make([]byte, 0)
-	return ret, 0, nil
+	return
 }
 
-func (mock *MockNodeClient) DumpStorage(address []byte) (storage *core_types.Storage, err error) {
-	return nil, nil
+func (mock *MockNodeClient) DumpStorage(address acm.Address) (storage *rpc.ResultDumpStorage, err error) {
+	return
 }
 
-func (mock *MockNodeClient) GetName(name string) (owner []byte, data string, expirationBlock int, err error) {
-	return nil, "", 0, nil
+func (mock *MockNodeClient) GetName(name string) (owner acm.Address, data string, expirationBlock uint64, err error) {
+	return
 }
 
-func (mock *MockNodeClient) ListValidators() (blockHeight int, bondedValidators, unbondingValidators []consensus_types.Validator, err error) {
-	return 0, nil, nil, nil
+func (mock *MockNodeClient) ListValidators() (blockHeight uint64, bondedValidators,
+	unbondingValidators []acm.Validator, err error) {
+	return
 }
 
 func (mock *MockNodeClient) Logger() logging_types.InfoTraceLogger {
diff --git a/client/node_client.go b/client/node_client.go
index a7d49a14568f92c5d19cf07e28ba93f921da2b2b..145adc5ffa59feaeb3fb85111c20ff3443ac5bc0 100644
--- a/client/node_client.go
+++ b/client/node_client.go
@@ -16,19 +16,14 @@ package client
 
 import (
 	"fmt"
-	// "strings"
 
-	"github.com/tendermint/go-rpc/client"
-
-	acc "github.com/hyperledger/burrow/account"
-	consensus_types "github.com/hyperledger/burrow/consensus/types"
-	core_types "github.com/hyperledger/burrow/core/types"
+	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/logging"
 	logging_types "github.com/hyperledger/burrow/logging/types"
-	tendermint_client "github.com/hyperledger/burrow/rpc/tendermint/client"
-	tendermint_types "github.com/hyperledger/burrow/rpc/tendermint/core/types"
+	"github.com/hyperledger/burrow/rpc"
+	tendermint_client "github.com/hyperledger/burrow/rpc/tm/client"
 	"github.com/hyperledger/burrow/txs"
-	tmLog15 "github.com/tendermint/log15"
+	"github.com/tendermint/tendermint/rpc/lib/client"
 )
 
 type NodeClient interface {
@@ -36,14 +31,14 @@ type NodeClient interface {
 	DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error)
 
 	Status() (ChainId []byte, ValidatorPublicKey []byte, LatestBlockHash []byte,
-		LatestBlockHeight int, LatestBlockTime int64, err error)
-	GetAccount(address []byte) (*acc.Account, error)
-	QueryContract(callerAddress, calleeAddress, data []byte) (ret []byte, gasUsed int64, err error)
-	QueryContractCode(address, code, data []byte) (ret []byte, gasUsed int64, err error)
+		LatestBlockHeight uint64, LatestBlockTime int64, err error)
+	GetAccount(address acm.Address) (acm.Account, error)
+	QueryContract(callerAddress, calleeAddress acm.Address, data []byte) (ret []byte, gasUsed uint64, err error)
+	QueryContractCode(address acm.Address, code, data []byte) (ret []byte, gasUsed uint64, 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)
+	DumpStorage(address acm.Address) (storage *rpc.ResultDumpStorage, err error)
+	GetName(name string) (owner acm.Address, data string, expirationBlock uint64, err error)
+	ListValidators() (blockHeight uint64, bondedValidators, unbondingValidators []acm.Validator, err error)
 
 	// Logging context for this NodeClient
 	Logger() logging_types.InfoTraceLogger
@@ -53,7 +48,7 @@ type NodeWebsocketClient interface {
 	Subscribe(eventId string) error
 	Unsubscribe(eventId string) error
 
-	WaitForConfirmation(tx txs.Tx, chainId string, inputAddr []byte) (chan Confirmation, error)
+	WaitForConfirmation(tx txs.Tx, chainId string, inputAddr acm.Address) (chan Confirmation, error)
 	Close()
 }
 
@@ -76,13 +71,6 @@ func NewBurrowNodeClient(rpcString string, logger logging_types.InfoTraceLogger)
 	}
 }
 
-// Note [Ben]: This is a hack to silence Tendermint logger from tendermint/go-rpc
-// it needs to be initialised before go-rpc, hence it's placement here.
-func init() {
-	h := tmLog15.LvlFilterHandler(tmLog15.LvlWarn, tmLog15.StdoutHandler)
-	tmLog15.Root().SetHandler(h)
-}
-
 //------------------------------------------------------------------------------------
 // broadcast to blockchain node
 
@@ -92,7 +80,7 @@ func (burrowNodeClient *burrowNodeClient) Broadcast(tx txs.Tx) (*txs.Receipt, er
 	if err != nil {
 		return nil, err
 	}
-	return &receipt, nil
+	return receipt, nil
 }
 
 func (burrowNodeClient *burrowNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error) {
@@ -133,13 +121,15 @@ func (burrowNodeClient *burrowNodeClient) DeriveWebsocketClient() (nodeWsClient
 
 // Status returns the ChainId (GenesisHash), validator's PublicKey, latest block hash
 // the block height and the latest block time.
-func (burrowNodeClient *burrowNodeClient) Status() (GenesisHash []byte, ValidatorPublicKey []byte, LatestBlockHash []byte, LatestBlockHeight int, LatestBlockTime int64, err error) {
+func (burrowNodeClient *burrowNodeClient) Status() (GenesisHash []byte, ValidatorPublicKey []byte,
+	LatestBlockHash []byte, LatestBlockHeight uint64, LatestBlockTime int64, err error) {
+
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
 	res, err := tendermint_client.Status(client)
 	if err != nil {
 		err = fmt.Errorf("Error connecting to node (%s) to get status: %s",
 			burrowNodeClient.broadcastRPC, err.Error())
-		return nil, nil, nil, int(0), int64(0), err
+		return
 	}
 
 	// unwrap return results
@@ -169,19 +159,23 @@ func (burrowNodeClient *burrowNodeClient) ChainId() (ChainName, ChainId string,
 
 // QueryContract executes the contract code at address with the given data
 // NOTE: there is no check on the caller;
-func (burrowNodeClient *burrowNodeClient) QueryContract(callerAddress, calleeAddress, data []byte) (ret []byte, gasUsed int64, err error) {
+func (burrowNodeClient *burrowNodeClient) QueryContract(callerAddress, calleeAddress acm.Address,
+	data []byte) (ret []byte, gasUsed uint64, err error) {
+
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
 	callResult, err := tendermint_client.Call(client, callerAddress, calleeAddress, data)
 	if err != nil {
 		err = fmt.Errorf("Error (%v) connnecting to node (%s) to query contract at (%X) with data (%X)",
 			err.Error(), burrowNodeClient.broadcastRPC, calleeAddress, data)
-		return nil, int64(0), err
+		return
 	}
 	return callResult.Return, callResult.GasUsed, nil
 }
 
 // QueryContractCode executes the contract code at address with the given data but with provided code
-func (burrowNodeClient *burrowNodeClient) QueryContractCode(address, code, data []byte) (ret []byte, gasUsed int64, err error) {
+func (burrowNodeClient *burrowNodeClient) QueryContractCode(address acm.Address, code,
+	data []byte) (ret []byte, gasUsed uint64, err error) {
+
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
 	// TODO: [ben] Call and CallCode have an inconsistent signature; it makes sense for both to only
 	// have a single address that is the contract to query.
@@ -189,13 +183,13 @@ func (burrowNodeClient *burrowNodeClient) QueryContractCode(address, code, data
 	if err != nil {
 		err = fmt.Errorf("Error connnecting to node (%s) to query contract code at (%X) with data (%X) and code (%X)",
 			burrowNodeClient.broadcastRPC, address, data, code, err.Error())
-		return nil, int64(0), err
+		return nil, uint64(0), err
 	}
 	return callResult.Return, callResult.GasUsed, nil
 }
 
 // GetAccount returns a copy of the account
-func (burrowNodeClient *burrowNodeClient) GetAccount(address []byte) (*acc.Account, error) {
+func (burrowNodeClient *burrowNodeClient) GetAccount(address acm.Address) (acm.Account, error) {
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
 	account, err := tendermint_client.GetAccount(client, address)
 	if err != nil {
@@ -208,35 +202,32 @@ func (burrowNodeClient *burrowNodeClient) GetAccount(address []byte) (*acc.Accou
 		return nil, err
 	}
 
-	return account.Copy(), nil
+	return account, nil
 }
 
-// DumpStorage returns the full storage for an account.
-func (burrowNodeClient *burrowNodeClient) DumpStorage(address []byte) (storage *core_types.Storage, err error) {
+// DumpStorage returns the full storage for an acm.
+func (burrowNodeClient *burrowNodeClient) DumpStorage(address acm.Address) (*rpc.ResultDumpStorage, error) {
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
 	resultStorage, err := tendermint_client.DumpStorage(client, address)
 	if err != nil {
-		err = fmt.Errorf("Error connecting to node (%s) to get storage for account (%X): %s",
+		return nil, fmt.Errorf("error connecting to node (%s) to get storage for account (%X): %s",
 			burrowNodeClient.broadcastRPC, address, err.Error())
-		return nil, err
 	}
-	// UnwrapResultDumpStorage is an inefficient full deep copy,
-	// to transform the type to /core/types.Storage
-	// TODO: removing go-wire and go-rpc allows us to collapse these types
-	storage = tendermint_types.UnwrapResultDumpStorage(resultStorage)
-	return
+	return resultStorage, nil
 }
 
 //--------------------------------------------------------------------------------------------
 // Name registry
 
-func (burrowNodeClient *burrowNodeClient) GetName(name string) (owner []byte, data string, expirationBlock int, err error) {
+func (burrowNodeClient *burrowNodeClient) GetName(name string) (owner acm.Address, data string,
+	expirationBlock uint64, err error) {
+
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
 	entryResult, err := tendermint_client.GetName(client, name)
 	if err != nil {
 		err = fmt.Errorf("Error connecting to node (%s) to get name registrar entry for name (%s)",
 			burrowNodeClient.broadcastRPC, name)
-		return nil, "", 0, err
+		return acm.ZeroAddress, "", 0, err
 	}
 	// unwrap return results
 	owner = entryResult.Owner
@@ -247,19 +238,25 @@ func (burrowNodeClient *burrowNodeClient) GetName(name string) (owner []byte, da
 
 //--------------------------------------------------------------------------------------------
 
-func (burrowNodeClient *burrowNodeClient) ListValidators() (blockHeight int,
-	bondedValidators []consensus_types.Validator, unbondingValidators []consensus_types.Validator, err error) {
+func (burrowNodeClient *burrowNodeClient) ListValidators() (blockHeight uint64,
+	bondedValidators, unbondingValidators []acm.Validator, err error) {
+
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
 	validatorsResult, err := tendermint_client.ListValidators(client)
 	if err != nil {
-		err = fmt.Errorf("Error connecting to node (%s) to get validators",
-			burrowNodeClient.broadcastRPC)
-		return 0, nil, nil, err
+		err = fmt.Errorf("Error connecting to node (%s) to get validators", burrowNodeClient.broadcastRPC)
+		return
 	}
 	// unwrap return results
 	blockHeight = validatorsResult.BlockHeight
-	bondedValidators = validatorsResult.BondedValidators
-	unbondingValidators = validatorsResult.UnbondingValidators
+	bondedValidators = make([]acm.Validator, len(validatorsResult.BondedValidators))
+	for i, cv := range validatorsResult.BondedValidators {
+		bondedValidators[i] = cv.Validator()
+	}
+	unbondingValidators = make([]acm.Validator, len(validatorsResult.UnbondingValidators))
+	for i, cv := range validatorsResult.UnbondingValidators {
+		unbondingValidators[i] = cv.Validator()
+	}
 	return
 }
 
diff --git a/client/rpc/client.go b/client/rpc/client.go
index d6d7b14e190efb6db5bc7c6c6fdfd3da6779cc76..a874a2ee38f01ae3885f9b2272c5052f0388cfd9 100644
--- a/client/rpc/client.go
+++ b/client/rpc/client.go
@@ -19,8 +19,9 @@ import (
 	"fmt"
 	"strconv"
 
-	ptypes "github.com/hyperledger/burrow/permission/types"
+	ptypes "github.com/hyperledger/burrow/permission"
 
+	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/client"
 	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/txs"
@@ -40,14 +41,14 @@ func Send(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr,
 		return nil, fmt.Errorf("destination address must be given with --to flag")
 	}
 
-	toAddrBytes, err := hex.DecodeString(toAddr)
+	toAddress, err := addressFromHexString(toAddr)
 	if err != nil {
-		return nil, fmt.Errorf("toAddr is bad hex: %v", err)
+		return nil, err
 	}
 
 	tx := txs.NewSendTx()
-	tx.AddInputWithNonce(pub, amt, int(nonce))
-	tx.AddOutput(toAddrBytes, amt)
+	tx.AddInputWithNonce(pub, amt, nonce)
+	tx.AddOutput(toAddress, amt)
 
 	return tx, nil
 }
@@ -58,17 +59,22 @@ func Call(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr,
 		return nil, err
 	}
 
-	toAddrBytes, err := hex.DecodeString(toAddr)
-	if err != nil {
-		return nil, fmt.Errorf("toAddr is bad hex: %v", err)
+	var toAddress *acm.Address
+
+	if toAddr != "" {
+		address, err := addressFromHexString(toAddr)
+		if err != nil {
+			return nil, fmt.Errorf("toAddr is bad hex: %v", err)
+		}
+		toAddress = &address
 	}
 
-	fee, err := strconv.ParseInt(feeS, 10, 64)
+	fee, err := strconv.ParseUint(feeS, 10, 64)
 	if err != nil {
 		return nil, fmt.Errorf("fee is misformatted: %v", err)
 	}
 
-	gas, err := strconv.ParseInt(gasS, 10, 64)
+	gas, err := strconv.ParseUint(gasS, 10, 64)
 	if err != nil {
 		return nil, fmt.Errorf("gas is misformatted: %v", err)
 	}
@@ -78,7 +84,7 @@ func Call(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr,
 		return nil, fmt.Errorf("data is bad hex: %v", err)
 	}
 
-	tx := txs.NewCallTxWithNonce(pub, toAddrBytes, dataBytes, amt, gas, fee, int(nonce))
+	tx := txs.NewCallTxWithNonce(pub, toAddress, dataBytes, amt, gas, fee, nonce)
 	return tx, nil
 }
 
@@ -88,12 +94,12 @@ func Name(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr,
 		return nil, err
 	}
 
-	fee, err := strconv.ParseInt(feeS, 10, 64)
+	fee, err := strconv.ParseUint(feeS, 10, 64)
 	if err != nil {
 		return nil, fmt.Errorf("fee is misformatted: %v", err)
 	}
 
-	tx := txs.NewNameTxWithNonce(pub, name, data, amt, fee, int(nonce))
+	tx := txs.NewNameTxWithNonce(pub, name, data, amt, fee, nonce)
 	return tx, nil
 }
 
@@ -102,7 +108,7 @@ func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 	if err != nil {
 		return nil, err
 	}
-	var args ptypes.PermArgs
+	var args *ptypes.PermArgs
 	switch permFunc {
 	case "setBase":
 		addr, pF, err := decodeAddressPermFlag(argsS[0], argsS[1])
@@ -120,13 +126,13 @@ func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 		} else {
 			return nil, fmt.Errorf("Unknown value %s", argsS[2])
 		}
-		args = &ptypes.SetBaseArgs{addr, pF, value}
+		args = ptypes.SetBaseArgs(addr, pF, value)
 	case "unsetBase":
 		addr, pF, err := decodeAddressPermFlag(argsS[0], argsS[1])
 		if err != nil {
 			return nil, err
 		}
-		args = &ptypes.UnsetBaseArgs{addr, pF}
+		args = ptypes.UnsetBaseArgs(addr, pF)
 	case "setGlobal":
 		pF, err := ptypes.PermStringToFlag(argsS[0])
 		if err != nil {
@@ -140,24 +146,24 @@ func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 		} else {
 			return nil, fmt.Errorf("Unknown value %s", argsS[1])
 		}
-		args = &ptypes.SetGlobalArgs{pF, value}
+		args = ptypes.SetGlobalArgs(pF, value)
 	case "addRole":
-		addr, err := hex.DecodeString(argsS[0])
+		address, err := addressFromHexString(argsS[0])
 		if err != nil {
 			return nil, err
 		}
-		args = &ptypes.AddRoleArgs{addr, argsS[1]}
+		args = ptypes.AddRoleArgs(address, argsS[1])
 	case "removeRole":
-		addr, err := hex.DecodeString(argsS[0])
+		address, err := addressFromHexString(argsS[0])
 		if err != nil {
 			return nil, err
 		}
-		args = &ptypes.RmRoleArgs{addr, argsS[1]}
+		args = ptypes.RemoveRoleArgs(address, argsS[1])
 	default:
-		return nil, fmt.Errorf("Invalid permission function for use in PermissionsTx: %s", permFunc)
+		return nil, fmt.Errorf("invalid permission function for use in PermissionsTx: %s", permFunc)
 	}
 	// args := snativeArgs(
-	tx := txs.NewPermissionsTxWithNonce(pub, args, int(nonce))
+	tx := txs.NewPermissionsTxWithNonce(pub, args, nonce)
 	return tx, nil
 }
 
@@ -167,7 +173,7 @@ func Bond(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, unbond
 	// if err != nil {
 	// 	return nil, err
 	// }
-	// var pubKey crypto.PubKeyEd25519
+	// var pubKey acm.PublicKeyEd25519
 	// var unbondAddrBytes []byte
 
 	// if unbondAddr == "" {
@@ -241,7 +247,7 @@ type TxResult struct {
 	Hash      []byte // all txs get a hash
 
 	// only CallTx
-	Address   []byte // only for new contracts
+	Address   *acm.Address // only for new contracts
 	Return    []byte
 	Exception string
 
@@ -252,7 +258,8 @@ 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 acm.Address
 	if sign {
 		inputAddr, tx, err = signTx(keyClient, chainID, tx)
 		if err != nil {
@@ -271,31 +278,34 @@ func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient ke
 			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
-					}
-					confirmation := <-confirmationChannel
-					if confirmation.Error != nil {
-						err = fmt.Errorf("Encountered error waiting for event: %s", confirmation.Error)
-						return
-					}
-					if confirmation.Exception != nil {
-						err = fmt.Errorf("Encountered Exception from chain: %s", confirmation.Exception)
-						return
-					}
-					txResult.BlockHash = confirmation.BlockHash
-					txResult.Exception = ""
-					eventDataTx, ok := confirmation.Event.(*txs.EventDataTx)
-					if !ok {
-						err = fmt.Errorf("Received wrong event type.")
-						return
-					}
-					txResult.Return = eventDataTx.Return
-				}()
 			}
+			defer func() {
+				if err != nil {
+					// if broadcast threw an error, just return
+					return
+				}
+				if txResult == nil {
+					err = fmt.Errorf("txResult unexpectedly not initialised in SignAndBroadcast")
+					return
+				}
+				confirmation := <-confirmationChannel
+				if confirmation.Error != nil {
+					err = fmt.Errorf("encountered error waiting for event: %s", confirmation.Error)
+					return
+				}
+				if confirmation.Exception != nil {
+					err = fmt.Errorf("encountered Exception from chain: %s", confirmation.Exception)
+					return
+				}
+				txResult.BlockHash = confirmation.BlockHash
+				txResult.Exception = ""
+				eventDataTx := confirmation.EventDataTx
+				if eventDataTx == nil {
+					err = fmt.Errorf("EventDataTx was nil")
+					return
+				}
+				txResult.Return = eventDataTx.Return
+			}()
 		}
 
 		var receipt *txs.Receipt
@@ -310,10 +320,19 @@ func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient ke
 		// reasonable to get this returned from the chain directly.  Alternatively,
 		// the benefit is that the we don't need to trust the chain node
 		if tx_, ok := tx.(*txs.CallTx); ok {
-			if len(tx_.Address) == 0 {
-				txResult.Address = txs.NewContractAddress(tx_.Input.Address, tx_.Input.Sequence)
+			if tx_.Address == nil {
+				address := acm.NewContractAddress(tx_.Input.Address, tx_.Input.Sequence)
+				txResult.Address = &address
 			}
 		}
 	}
 	return
 }
+
+func addressFromHexString(addrString string) (acm.Address, error) {
+	addrBytes, err := hex.DecodeString(addrString)
+	if err != nil {
+		return acm.Address{}, err
+	}
+	return acm.AddressFromBytes(addrBytes)
+}
diff --git a/client/rpc/client_test.go b/client/rpc/client_test.go
index 603fe793fe2f7e32e9c355f8c5150f797428283c..c731e491d28340fc56c85767810e7b17b87f9e79 100644
--- a/client/rpc/client_test.go
+++ b/client/rpc/client_test.go
@@ -22,6 +22,7 @@ import (
 
 	mockclient "github.com/hyperledger/burrow/client/mock"
 	mockkeys "github.com/hyperledger/burrow/keys/mock"
+	"github.com/stretchr/testify/require"
 )
 
 func Test(t *testing.T) {
@@ -40,7 +41,7 @@ func testSend(t *testing.T,
 	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
-	addressString := fmt.Sprintf("%X", keyClient.NewKey())
+	addressString := keyClient.NewKey().String()
 	// Public key can be queried from mockKeyClient.PublicKey(address)
 	// but here we let the transaction factory retrieve the public key
 	// which will then also overwrite the address we provide the function.
@@ -48,7 +49,7 @@ func testSend(t *testing.T,
 	// to address in generated transation.
 	publicKeyString := ""
 	// generate an additional address to send amount to
-	toAddressString := fmt.Sprintf("%X", keyClient.NewKey())
+	toAddressString := keyClient.NewKey().String()
 	// set an amount to transfer
 	amountString := "1000"
 	// unset nonce so that we retrieve nonce from account
@@ -56,10 +57,7 @@ func testSend(t *testing.T,
 
 	_, err := Send(nodeClient, keyClient, publicKeyString, addressString,
 		toAddressString, amountString, nonceString)
-	if err != nil {
-		t.Logf("Error in SendTx: %s", err)
-		t.Fail()
-	}
+	require.NoError(t, err, "Error in Send")
 	// assert.NotEqual(t, txSend)
 	// TODO: test content of Transaction
 }
@@ -68,7 +66,7 @@ func testCall(t *testing.T,
 	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
-	addressString := fmt.Sprintf("%X", keyClient.NewKey())
+	addressString := keyClient.NewKey().String()
 	// Public key can be queried from mockKeyClient.PublicKey(address)
 	// but here we let the transaction factory retrieve the public key
 	// which will then also overwrite the address we provide the function.
@@ -76,7 +74,7 @@ func testCall(t *testing.T,
 	// to address in generated transation.
 	publicKeyString := ""
 	// generate an additional address to send amount to
-	toAddressString := fmt.Sprintf("%X", keyClient.NewKey())
+	toAddressString := keyClient.NewKey().String()
 	// set an amount to transfer
 	amountString := "1000"
 	// unset nonce so that we retrieve nonce from account
@@ -101,7 +99,7 @@ func testName(t *testing.T,
 	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
-	addressString := fmt.Sprintf("%X", keyClient.NewKey())
+	addressString := keyClient.NewKey().String()
 	// Public key can be queried from mockKeyClient.PublicKey(address)
 	// but here we let the transaction factory retrieve the public key
 	// which will then also overwrite the address we provide the function.
@@ -132,7 +130,7 @@ func testPermissions(t *testing.T,
 	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
-	addressString := fmt.Sprintf("%X", keyClient.NewKey())
+	addressString := keyClient.NewKey().String()
 	// Public key can be queried from mockKeyClient.PublicKey(address)
 	// but here we let the transaction factory retrieve the public key
 	// which will then also overwrite the address we provide the function.
@@ -140,7 +138,7 @@ func testPermissions(t *testing.T,
 	// to address in generated transation.
 	publicKeyString := ""
 	// generate an additional address to set permissions for
-	permAddressString := fmt.Sprintf("%X", keyClient.NewKey())
+	permAddressString := keyClient.NewKey().String()
 	// unset nonce so that we retrieve nonce from account
 	nonceString := ""
 
diff --git a/client/rpc/client_util.go b/client/rpc/client_util.go
index 6711c1ad5cb6cbcd20bb96b43068b0d22ec418b1..02e6ae056541ed97a720164b5f6928b490fc10dd 100644
--- a/client/rpc/client_util.go
+++ b/client/rpc/client_util.go
@@ -19,14 +19,14 @@ import (
 	"fmt"
 	"strconv"
 
-	"github.com/tendermint/go-crypto"
-
-	acc "github.com/hyperledger/burrow/account"
+	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/client"
 	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/logging"
+	"github.com/hyperledger/burrow/permission"
 	ptypes "github.com/hyperledger/burrow/permission/types"
 	"github.com/hyperledger/burrow/txs"
+	"github.com/tendermint/go-crypto"
 )
 
 //------------------------------------------------------------------------------------
@@ -34,65 +34,71 @@ import (
 
 // tx has either one input or we default to the first one (ie for send/bond)
 // TODO: better support for multisig and bonding
-func signTx(keyClient keys.KeyClient, chainID string, tx_ txs.Tx) ([]byte, txs.Tx, error) {
-	signBytesString := fmt.Sprintf("%X", acc.SignBytes(chainID, tx_))
-	var inputAddr []byte
-	var sigED crypto.SignatureEd25519
+func signTx(keyClient keys.KeyClient, chainID string, tx_ txs.Tx) (acm.Address, txs.Tx, error) {
+	signBytes := acm.SignBytes(chainID, tx_)
+	var err error
 	switch tx := tx_.(type) {
 	case *txs.SendTx:
-		inputAddr = tx.Inputs[0].Address
-		defer func(s *crypto.SignatureEd25519) { tx.Inputs[0].Signature = *s }(&sigED)
+		signAddress := tx.Inputs[0].Address
+		tx.Inputs[0].Signature, err = keyClient.Sign(signAddress, signBytes)
+		return signAddress, tx, err
+
 	case *txs.NameTx:
-		inputAddr = tx.Input.Address
-		defer func(s *crypto.SignatureEd25519) { tx.Input.Signature = *s }(&sigED)
+		signAddress := tx.Input.Address
+		tx.Input.Signature, err = keyClient.Sign(signAddress, signBytes)
+		return signAddress, tx, err
+
 	case *txs.CallTx:
-		inputAddr = tx.Input.Address
-		defer func(s *crypto.SignatureEd25519) { tx.Input.Signature = *s }(&sigED)
+		signAddress := tx.Input.Address
+		tx.Input.Signature, err = keyClient.Sign(signAddress, signBytes)
+		return signAddress, tx, err
+
 	case *txs.PermissionsTx:
-		inputAddr = tx.Input.Address
-		defer func(s *crypto.SignatureEd25519) { tx.Input.Signature = *s }(&sigED)
+		signAddress := tx.Input.Address
+		tx.Input.Signature, err = keyClient.Sign(signAddress, signBytes)
+		return signAddress, tx, err
+
 	case *txs.BondTx:
-		inputAddr = tx.Inputs[0].Address
-		defer func(s *crypto.SignatureEd25519) {
-			tx.Signature = *s
-			tx.Inputs[0].Signature = *s
-		}(&sigED)
+		signAddress := tx.Inputs[0].Address
+		tx.Signature, err = keyClient.Sign(signAddress, signBytes)
+		tx.Inputs[0].Signature = tx.Signature
+		return signAddress, tx, err
+
 	case *txs.UnbondTx:
-		inputAddr = tx.Address
-		defer func(s *crypto.SignatureEd25519) { tx.Signature = *s }(&sigED)
+		signAddress := tx.Address
+		tx.Signature, err = keyClient.Sign(signAddress, signBytes)
+		return signAddress, tx, err
+
 	case *txs.RebondTx:
-		inputAddr = tx.Address
-		defer func(s *crypto.SignatureEd25519) { tx.Signature = *s }(&sigED)
-	}
-	sig, err := keyClient.Sign(signBytesString, inputAddr)
-	if err != nil {
-		return nil, nil, err
+		signAddress := tx.Address
+		tx.Signature, err = keyClient.Sign(signAddress, signBytes)
+		return signAddress, tx, err
+
+	default:
+		return acm.ZeroAddress, nil, fmt.Errorf("unknown transaction type for signTx: %#v", tx_)
 	}
-	// TODO: [ben] temporarily address the type conflict here, to be cleaned up
-	// with full type restructuring
-	var sig64 [64]byte
-	copy(sig64[:], sig)
-	sigED = crypto.SignatureEd25519(sig64)
-	return inputAddr, tx_, nil
 }
 
-func decodeAddressPermFlag(addrS, permFlagS string) (addr []byte, pFlag ptypes.PermFlag, err error) {
-	if addr, err = hex.DecodeString(addrS); err != nil {
+func decodeAddressPermFlag(addrS, permFlagS string) (addr acm.Address, pFlag ptypes.PermFlag, err error) {
+	var addrBytes []byte
+	if addrBytes, err = hex.DecodeString(addrS); err != nil {
+		copy(addr[:], addrBytes)
 		return
 	}
-	if pFlag, err = ptypes.PermStringToFlag(permFlagS); err != nil {
+	if pFlag, err = permission.PermStringToFlag(permFlagS); err != nil {
 		return
 	}
 	return
 }
 
-func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, amtS, nonceS string) (pub crypto.PubKey, amt int64, nonce int64, err error) {
+func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, amtS,
+	nonceS string) (pub acm.PublicKey, amt uint64, nonce uint64, err error) {
+
 	if amtS == "" {
 		err = fmt.Errorf("input must specify an amount with the --amt flag")
 		return
 	}
 
-	var pubKeyBytes []byte
 	if pubkey == "" && addr == "" {
 		err = fmt.Errorf("at least one of --pubkey or --addr must be given")
 		return
@@ -103,11 +109,16 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 				"address", addr,
 			)
 		}
+		var pubKeyBytes []byte
 		pubKeyBytes, err = hex.DecodeString(pubkey)
 		if err != nil {
 			err = fmt.Errorf("pubkey is bad hex: %v", err)
 			return
 		}
+
+		pubKeyEd25519 := crypto.PubKeyEd25519{}
+		copy(pubKeyEd25519[:], pubKeyBytes)
+		pub = acm.PublicKeyFromPubKey(pubKeyEd25519.Wrap())
 	} else {
 		// grab the pubkey from monax-keys
 		addressBytes, err2 := hex.DecodeString(addr)
@@ -115,45 +126,42 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 			err = fmt.Errorf("Bad hex string for address (%s): %v", addr, err)
 			return
 		}
-		pubKeyBytes, err2 = keyClient.PublicKey(addressBytes)
+		address, err2 := acm.AddressFromBytes(addressBytes)
+		if err2 != nil {
+			err = fmt.Errorf("Could not convert bytes (%X) to address: %v", addressBytes, err2)
+		}
+		pub, err2 = keyClient.PublicKey(address)
 		if err2 != nil {
 			err = fmt.Errorf("Failed to fetch pubkey for address (%s): %v", addr, err2)
 			return
 		}
 	}
 
-	if len(pubKeyBytes) == 0 {
-		err = fmt.Errorf("Error resolving public key")
-		return
-	}
+	var address acm.Address
+	address = pub.Address()
 
-	amt, err = strconv.ParseInt(amtS, 10, 64)
+	amt, err = strconv.ParseUint(amtS, 10, 64)
 	if err != nil {
 		err = fmt.Errorf("amt is misformatted: %v", err)
 	}
 
-	var pubArray [32]byte
-	copy(pubArray[:], pubKeyBytes)
-	pub = crypto.PubKeyEd25519(pubArray)
-	addrBytes := pub.Address()
-
 	if nonceS == "" {
 		if nodeClient == nil {
 			err = fmt.Errorf("input must specify a nonce with the --nonce flag or use --node-addr (or BURROW_CLIENT_NODE_ADDR) to fetch the nonce from a node")
 			return
 		}
 		// fetch nonce from node
-		account, err2 := nodeClient.GetAccount(addrBytes)
+		account, err2 := nodeClient.GetAccount(address)
 		if err2 != nil {
 			return pub, amt, nonce, err2
 		}
-		nonce = int64(account.Sequence) + 1
+		nonce = account.Sequence() + 1
 		logging.TraceMsg(nodeClient.Logger(), "Fetch nonce from node",
 			"nonce", nonce,
-			"account address", addrBytes,
+			"account address", address,
 		)
 	} else {
-		nonce, err = strconv.ParseInt(nonceS, 10, 64)
+		nonce, err = strconv.ParseUint(nonceS, 10, 64)
 		if err != nil {
 			err = fmt.Errorf("nonce is misformatted: %v", err)
 			return
diff --git a/client/websocket_client.go b/client/websocket_client.go
index 428f78fd66498efb40cdf380c5f71bf0f0eb1870..6f943ae9c9dafceecfbce8fe46f9ab976fcc776e 100644
--- a/client/websocket_client.go
+++ b/client/websocket_client.go
@@ -19,14 +19,17 @@ import (
 	"fmt"
 	"time"
 
-	logging_types "github.com/hyperledger/burrow/logging/types"
-	"github.com/tendermint/go-rpc/client"
-	"github.com/tendermint/go-wire"
+	"encoding/json"
 
+	"github.com/hyperledger/burrow/account"
+	exe_events "github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/logging"
-	tendermint_client "github.com/hyperledger/burrow/rpc/tendermint/client"
-	ctypes "github.com/hyperledger/burrow/rpc/tendermint/core/types"
+	logging_types "github.com/hyperledger/burrow/logging/types"
+	"github.com/hyperledger/burrow/rpc"
+	tendermint_client "github.com/hyperledger/burrow/rpc/tm/client"
 	"github.com/hyperledger/burrow/txs"
+	"github.com/tendermint/tendermint/rpc/lib/client"
+	tm_types "github.com/tendermint/tendermint/types"
 )
 
 const (
@@ -34,10 +37,10 @@ const (
 )
 
 type Confirmation struct {
-	BlockHash []byte
-	Event     txs.EventData
-	Exception error
-	Error     error
+	BlockHash   []byte
+	EventDataTx *exe_events.EventDataTx
+	Exception   error
+	Error       error
 }
 
 // NOTE [ben] Compiler check to ensure burrowNodeClient successfully implements
@@ -65,37 +68,40 @@ func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) Unsubscribe(subscrip
 
 // 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 (burrowNodeWebsocketClient *burrowNodeWebsocketClient) WaitForConfirmation(tx txs.Tx, chainId string, inputAddr []byte) (chan Confirmation, error) {
-	// check no errors are reported on the websocket
-	if err := burrowNodeWebsocketClient.assertNoErrors(); err != nil {
-		return nil, err
-	}
+func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) WaitForConfirmation(tx txs.Tx, chainId string,
+	inputAddr account.Address) (chan Confirmation, error) {
 
 	// Setup the confirmation channel to be returned
 	confirmationChannel := make(chan Confirmation, 1)
 	var latestBlockHash []byte
 
-	eid := txs.EventStringAccInput(inputAddr)
+	eid := exe_events.EventStringAccInput(inputAddr)
 	if err := burrowNodeWebsocketClient.Subscribe(eid); err != nil {
 		return nil, fmt.Errorf("Error subscribing to AccInput event (%s): %v", eid, err)
 	}
-	if err := burrowNodeWebsocketClient.Subscribe(txs.EventStringNewBlock()); err != nil {
+	if err := burrowNodeWebsocketClient.Subscribe(tm_types.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 := <-burrowNodeWebsocketClient.tendermintWebsocket.ResultsCh
-			result := new(ctypes.BurrowResult)
-			if wire.ReadJSONPtr(result, resultBytes, &err); err != nil {
+			response := <-burrowNodeWebsocketClient.tendermintWebsocket.ResponsesCh
+			if response.Error != nil {
+				logging.InfoMsg(burrowNodeWebsocketClient.logger,
+					"Error received on websocket channel", "error", err)
+				continue
+			}
+			result := new(rpc.Result)
+
+			if json.Unmarshal(*response.Result, result); err != nil {
 				// keep calm and carry on
-				logging.InfoMsg(burrowNodeWebsocketClient.logger, "Failed to unmarshal json bytes for websocket event",
-					"error", err)
+				logging.InfoMsg(burrowNodeWebsocketClient.logger,
+					"Failed to unmarshal json bytes for websocket event", "error", err)
 				continue
 			}
 
-			subscription, ok := (*result).(*ctypes.ResultSubscribe)
+			subscription, ok := result.Unwrap().(*rpc.ResultSubscribe)
 			if ok {
 				// Received confirmation of subscription to event streams
 				// TODO: collect subscription IDs, push into channel and on completion
@@ -106,16 +112,16 @@ func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) WaitForConfirmation(
 				continue
 			}
 
-			event, ok := (*result).(*ctypes.ResultEvent)
+			resultEvent, ok := result.Unwrap().(*rpc.ResultEvent)
 			if !ok {
 				// keep calm and carry on
 				logging.InfoMsg(burrowNodeWebsocketClient.logger, "Failed to cast to ResultEvent for websocket event",
-					"event", event.Event)
+					"event", resultEvent.Event)
 				continue
 			}
 
-			blockData, ok := event.Data.(txs.EventDataNewBlock)
-			if ok {
+			blockData := resultEvent.EventDataNewBlock()
+			if blockData != nil {
 				latestBlockHash = blockData.Block.Hash()
 				logging.TraceMsg(burrowNodeWebsocketClient.logger, "Registered new block",
 					"block", blockData.Block,
@@ -136,47 +142,47 @@ func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) WaitForConfirmation(
 			// 	continue
 			// }
 
-			if event.Event != eid {
+			if resultEvent.Event != eid {
 				logging.InfoMsg(burrowNodeWebsocketClient.logger, "Received unsolicited event",
-					"event_received", event.Event,
+					"event_received", resultEvent.Event,
 					"event_expected", eid)
 				continue
 			}
 
-			data, ok := event.Data.(txs.EventDataTx)
-			if !ok {
+			eventDataTx := resultEvent.EventDataTx()
+			if eventDataTx == nil {
 				// 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,
+					BlockHash:   latestBlockHash,
+					EventDataTx: 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)) {
+			if !bytes.Equal(txs.TxHash(chainId, eventDataTx.Tx), txs.TxHash(chainId, tx)) {
 				logging.TraceMsg(burrowNodeWebsocketClient.logger, "Received different event",
 					// TODO: consider re-implementing TxID again, or other more clear debug
-					"received transaction event", txs.TxHash(chainId, data.Tx))
+					"received transaction event", txs.TxHash(chainId, eventDataTx.Tx))
 				continue
 			}
 
-			if data.Exception != "" {
+			if eventDataTx.Exception != "" {
 				confirmationChannel <- Confirmation{
-					BlockHash: latestBlockHash,
-					Event:     &data,
-					Exception: fmt.Errorf("Transaction confirmed with exception: %v", data.Exception),
-					Error:     nil,
+					BlockHash:   latestBlockHash,
+					EventDataTx: eventDataTx,
+					Exception:   fmt.Errorf("Transaction confirmed with exception: %v", eventDataTx.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,
+				BlockHash:   latestBlockHash,
+				EventDataTx: eventDataTx,
+				Exception:   nil,
+				Error:       nil,
 			}
 			return
 		}
@@ -190,10 +196,10 @@ func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) WaitForConfirmation(
 	go func() {
 		<-timeout
 		confirmationChannel <- Confirmation{
-			BlockHash: nil,
-			Event:     nil,
-			Exception: nil,
-			Error:     fmt.Errorf("timed out waiting for event"),
+			BlockHash:   nil,
+			EventDataTx: nil,
+			Exception:   nil,
+			Error:       fmt.Errorf("timed out waiting for event"),
 		}
 	}()
 	return confirmationChannel, nil
@@ -204,16 +210,3 @@ func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) Close() {
 		burrowNodeWebsocketClient.tendermintWebsocket.Stop()
 	}
 }
-
-func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) assertNoErrors() error {
-	if burrowNodeWebsocketClient.tendermintWebsocket != nil {
-		select {
-		case err := <-burrowNodeWebsocketClient.tendermintWebsocket.ErrorsCh:
-			return err
-		default:
-			return nil
-		}
-	} else {
-		return fmt.Errorf("burrow-client has no websocket initialised.")
-	}
-}