diff --git a/core/integration/test_wrapper.go b/core/integration/test_wrapper.go
new file mode 100644
index 0000000000000000000000000000000000000000..b532e4e1021b1171e5ae9f156468bb569a3bac79
--- /dev/null
+++ b/core/integration/test_wrapper.go
@@ -0,0 +1,128 @@
+// +build integration
+
+// Space above here matters
+// Copyright 2017 Monax Industries Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package integration
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"strconv"
+	"time"
+
+	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/consensus/tendermint/validator"
+	"github.com/hyperledger/burrow/core"
+	"github.com/hyperledger/burrow/genesis"
+	"github.com/hyperledger/burrow/keys/mock"
+	"github.com/hyperledger/burrow/logging"
+	"github.com/hyperledger/burrow/logging/config"
+	"github.com/hyperledger/burrow/logging/lifecycle"
+	"github.com/hyperledger/burrow/permission"
+	"github.com/hyperledger/burrow/rpc"
+	tm_config "github.com/tendermint/tendermint/config"
+)
+
+const (
+	chainName = "Integration_Test_Chain"
+	testDir   = "./test_scratch/tm_test"
+)
+
+// Enable logger output during tests
+var debugLogging = false
+
+// We use this to wrap tests
+func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.GenesisDoc, runner func() int) int {
+	fmt.Println("Running with integration TestWrapper (core/integration/test_wrapper.go)...")
+
+	os.RemoveAll(testDir)
+	os.MkdirAll(testDir, 0777)
+	os.Chdir(testDir)
+
+	tmConf := tm_config.DefaultConfig()
+	logger := logging.NewNoopLogger()
+	if debugLogging {
+		var err error
+		// Change config as needed
+		logger, err = lifecycle.NewLoggerFromLoggingConfig(&config.LoggingConfig{
+			RootSink: config.Sink().
+				SetTransform(config.FilterTransform(config.IncludeWhenAnyMatches,
+					//"","",
+					"method", "GetAccount",
+					"method", "BroadcastTx",
+					"tag", "sequence",
+					"tag", "Commit",
+					"tag", "CheckTx",
+					"tag", "DeliverTx",
+				)).
+				//AddSinks(config.Sink().SetTransform(config.FilterTransform(config.ExcludeWhenAnyMatches, "run_call", "false")).
+				AddSinks(config.Sink().SetTransform(config.PruneTransform("log_channel", "trace", "scope", "returns", "run_id", "args")).
+					AddSinks(config.Sink().SetTransform(config.SortTransform("tx_hash", "time", "message", "method")).
+						SetOutput(config.StdoutOutput()))),
+		})
+		if err != nil {
+			panic(err)
+		}
+	}
+
+	validatorAccount := privateAccounts[0]
+	privValidator := validator.NewPrivValidatorMemory(validatorAccount, validatorAccount)
+	keyClient := mock.NewMockKeyClient(privateAccounts...)
+	kernel, err := core.NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, rpc.DefaultRPCConfig(),
+		nil, logger)
+	if err != nil {
+		panic(err)
+	}
+	// Sometimes better to not shutdown as logging errors on shutdown may obscure real issue
+	defer func() {
+		//kernel.Shutdown(context.Background())
+	}()
+
+	err = kernel.Boot()
+	if err != nil {
+		panic(err)
+	}
+
+	return runner()
+}
+
+func TestGenesisDoc(addressables []acm.PrivateAccount) *genesis.GenesisDoc {
+	accounts := make(map[string]acm.Account, len(addressables))
+	for i, pa := range addressables {
+		account := acm.FromAddressable(pa)
+		account.AddToBalance(1 << 32)
+		account.SetPermissions(permission.AllAccountPermissions.Clone())
+		accounts[fmt.Sprintf("user_%v", i)] = account
+	}
+	genesisTime, err := time.Parse("02-01-2006", "27-10-2017")
+	if err != nil {
+		panic("could not parse test genesis time")
+	}
+	return genesis.MakeGenesisDocFromAccounts(chainName, nil, genesisTime, accounts,
+		map[string]acm.Validator{
+			"genesis_validator": acm.AsValidator(accounts["user_0"]),
+		})
+}
+
+// Deterministic account generation helper. Pass number of accounts to make
+func MakePrivateAccounts(n int) []acm.PrivateAccount {
+	accounts := make([]acm.PrivateAccount, n)
+	for i := 0; i < n; i++ {
+		accounts[i] = acm.GeneratePrivateAccountFromSecret("mysecret" + strconv.Itoa(i))
+	}
+	return accounts
+}
diff --git a/genesis/deterministic_genesis.go b/genesis/deterministic_genesis.go
index eeac035ed1ed25489c5b05d7c055b7ede8884a43..de80e258883a9598a7ab32ce5310952d6d9ad95b 100644
--- a/genesis/deterministic_genesis.go
+++ b/genesis/deterministic_genesis.go
@@ -21,10 +21,10 @@ func NewDeterministicGenesis(seed int64) *deterministicGenesis {
 }
 
 func (dg *deterministicGenesis) GenesisDoc(numAccounts int, randBalance bool, minBalance uint64, numValidators int,
-	randBonded bool, minBonded int64) (*GenesisDoc, []acm.SigningAccount, []acm.SigningAccount) {
+	randBonded bool, minBonded int64) (*GenesisDoc, []acm.AddressableSigner, []acm.AddressableSigner) {
 
 	accounts := make([]Account, numAccounts)
-	privAccounts := make([]acm.SigningAccount, numAccounts)
+	privAccounts := make([]acm.AddressableSigner, numAccounts)
 	defaultPerms := permission.DefaultAccountPermissions
 	for i := 0; i < numAccounts; i++ {
 		account, privAccount := dg.Account(randBalance, minBalance)
@@ -38,7 +38,7 @@ func (dg *deterministicGenesis) GenesisDoc(numAccounts int, randBalance bool, mi
 		privAccounts[i] = privAccount
 	}
 	validators := make([]Validator, numValidators)
-	privValidators := make([]acm.SigningAccount, numValidators)
+	privValidators := make([]acm.AddressableSigner, numValidators)
 	for i := 0; i < numValidators; i++ {
 		validator := acm.GeneratePrivateAccountFromSecret(fmt.Sprintf("val_%v", i))
 		privValidators[i] = validator
@@ -65,7 +65,7 @@ func (dg *deterministicGenesis) GenesisDoc(numAccounts int, randBalance bool, mi
 
 }
 
-func (dg *deterministicGenesis) Account(randBalance bool, minBalance uint64) (acm.Account, acm.SigningAccount) {
+func (dg *deterministicGenesis) Account(randBalance bool, minBalance uint64) (acm.Account, acm.AddressableSigner) {
 	privateKey, err := acm.GeneratePrivateKey(dg.random)
 	if err != nil {
 		panic(fmt.Errorf("could not generate private key deterministically"))
diff --git a/keys/mock/key_client_mock.go b/keys/mock/key_client_mock.go
index 2254c1105c7577c8dfef4e3f98068ce841c03e5a..96a614cac83ebe8367a84e76fad91563a1198375 100644
--- a/keys/mock/key_client_mock.go
+++ b/keys/mock/key_client_mock.go
@@ -59,6 +59,19 @@ func newMockKey() (*MockKey, error) {
 	return key, nil
 }
 
+func mockKeyFromPrivateAccount(privateAccount acm.PrivateAccount) *MockKey {
+	_, ok := privateAccount.PrivateKey().Unwrap().(crypto.PrivKeyEd25519)
+	if !ok {
+		panic(fmt.Errorf("mock key client only supports ed25519 private keys at present"))
+	}
+	key := &MockKey{
+		Address:   privateAccount.Address(),
+		PublicKey: privateAccount.PublicKey().RawBytes(),
+	}
+	copy(key.PrivateKey[:], privateAccount.PrivateKey().RawBytes())
+	return key
+}
+
 func (mockKey *MockKey) Sign(message []byte) (acm.Signature, error) {
 	return acm.SignatureFromBytes(ed25519.Sign(&mockKey.PrivateKey, message)[:])
 }
@@ -73,10 +86,14 @@ type MockKeyClient struct {
 	knownKeys map[acm.Address]*MockKey
 }
 
-func NewMockKeyClient() *MockKeyClient {
-	return &MockKeyClient{
+func NewMockKeyClient(privateAccounts ...acm.PrivateAccount) *MockKeyClient {
+	client := &MockKeyClient{
 		knownKeys: make(map[acm.Address]*MockKey),
 	}
+	for _, pa := range privateAccounts {
+		client.knownKeys[pa.Address()] = mockKeyFromPrivateAccount(pa)
+	}
+	return client
 }
 
 func (mock *MockKeyClient) NewKey() acm.Address {
diff --git a/rpc/tm/integration/shared.go b/rpc/tm/integration/shared.go
index bd7fb72e49b059a99330b59efe5a867fd3b56a00..0f4ba18a5091a7d251fe6ba49472a3d8e1fe6c90 100644
--- a/rpc/tm/integration/shared.go
+++ b/rpc/tm/integration/shared.go
@@ -19,48 +19,29 @@ package integration
 
 import (
 	"bytes"
-	"context"
-	"fmt"
 	"hash/fnv"
-	"strconv"
 	"testing"
 
-	"os"
-
-	"time"
-
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/consensus/tendermint/validator"
-	"github.com/hyperledger/burrow/core"
+	"github.com/hyperledger/burrow/core/integration"
 	"github.com/hyperledger/burrow/execution"
-	"github.com/hyperledger/burrow/genesis"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/hyperledger/burrow/logging/config"
-	"github.com/hyperledger/burrow/logging/lifecycle"
-	"github.com/hyperledger/burrow/permission"
 	"github.com/hyperledger/burrow/rpc"
 	tm_client "github.com/hyperledger/burrow/rpc/tm/client"
 	"github.com/hyperledger/burrow/txs"
 	"github.com/stretchr/testify/require"
-	tm_config "github.com/tendermint/tendermint/config"
 	"github.com/tendermint/tendermint/rpc/lib/client"
 )
 
 const (
-	chainName         = "RPC_Test_Chain"
 	rpcAddr           = "0.0.0.0:46657"
 	websocketAddr     = rpcAddr
 	websocketEndpoint = "/websocket"
-	testDir           = "./test_scratch/tm_test"
 )
 
-// Enable logger output during tests
-var debugLogging = false
-
 // global variables for use across all tests
 var (
-	privateAccounts = makePrivateAccounts(5) // make keys
+	privateAccounts = integration.MakePrivateAccounts(5) // make keys
 	jsonRpcClient   = rpcclient.NewJSONRPCClient(rpcAddr)
 	httpClient      = rpcclient.NewURIClient(rpcAddr)
 	clients         = map[string]tm_client.RPCClient{
@@ -68,90 +49,9 @@ var (
 		"HTTP":    httpClient,
 	}
 	// Initialised in initGlobalVariables
-	genesisDoc = new(genesis.GenesisDoc)
+	genesisDoc = integration.TestGenesisDoc(privateAccounts)
 )
 
-// We use this to wrap tests
-func TestWrapper(runner func() int) int {
-	fmt.Println("Running with integration TestWrapper (rpc/tm/integration/shared.go)...")
-
-	os.RemoveAll(testDir)
-	os.MkdirAll(testDir, 0777)
-	os.Chdir(testDir)
-
-	tmConf := tm_config.DefaultConfig()
-	logger := logging.NewNoopLogger()
-	if debugLogging {
-		var err error
-		// Change config as needed
-		logger, err = lifecycle.NewLoggerFromLoggingConfig(&config.LoggingConfig{
-			RootSink: config.Sink().
-				SetTransform(config.FilterTransform(config.IncludeWhenAnyMatches,
-					//"","",
-					"method", "GetAccount",
-					"method", "BroadcastTx",
-					"tag", "sequence",
-					"tag", "Commit",
-					"tag", "CheckTx",
-					"tag", "DeliverTx",
-				)).
-				//AddSinks(config.Sink().SetTransform(config.FilterTransform(config.ExcludeWhenAnyMatches, "run_call", "false")).
-				AddSinks(config.Sink().SetTransform(config.PruneTransform("log_channel", "trace", "scope", "returns", "run_id", "args")).
-					AddSinks(config.Sink().SetTransform(config.SortTransform("tx_hash", "time", "message", "method")).
-						SetOutput(config.StdoutOutput()))),
-		})
-		if err != nil {
-			panic(err)
-		}
-	}
-
-	privValidator := validator.NewPrivValidatorMemory(privateAccounts[0], privateAccounts[0])
-	genesisDoc = testGenesisDoc()
-	kernel, err := core.NewKernel(context.Background(), privValidator, genesisDoc, tmConf, rpc.DefaultRPCConfig(),
-		nil, logger)
-	if err != nil {
-		panic(err)
-	}
-	// Sometimes better to not shutdown as logging errors on shutdown may obscure real issue
-	defer func() {
-		//kernel.Shutdown(context.Background())
-	}()
-
-	err = kernel.Boot()
-	if err != nil {
-		panic(err)
-	}
-
-	return runner()
-}
-
-func testGenesisDoc() *genesis.GenesisDoc {
-	accounts := make(map[string]acm.Account, len(privateAccounts))
-	for i, pa := range privateAccounts {
-		account := acm.FromAddressable(pa)
-		account.AddToBalance(1 << 32)
-		account.SetPermissions(permission.AllAccountPermissions.Clone())
-		accounts[fmt.Sprintf("user_%v", i)] = account
-	}
-	genesisTime, err := time.Parse("02-01-2006", "27-10-2017")
-	if err != nil {
-		panic("could not parse test genesis time")
-	}
-	return genesis.MakeGenesisDocFromAccounts(chainName, nil, genesisTime, accounts,
-		map[string]acm.Validator{
-			"genesis_validator": acm.AsValidator(accounts["user_0"]),
-		})
-}
-
-// Deterministic account generation helper. Pass number of accounts to make
-func makePrivateAccounts(n int) []acm.SigningAccount {
-	accounts := make([]acm.SigningAccount, n)
-	for i := 0; i < n; i++ {
-		accounts[i] = acm.GeneratePrivateAccountFromSecret("mysecret" + strconv.Itoa(i))
-	}
-	return accounts
-}
-
 //-------------------------------------------------------------------------------
 // some default transaction functions
 
diff --git a/rpc/tm/integration/shared_test.go b/rpc/tm/integration/shared_test.go
index 9e8f1d17d1dc0d498b145a7dbe9767c6549eb643..55a2a5b0b4e99955bae50b118c1529d8ba438981 100644
--- a/rpc/tm/integration/shared_test.go
+++ b/rpc/tm/integration/shared_test.go
@@ -21,11 +21,13 @@ import (
 	"os"
 	"testing"
 	"time"
+
+	"github.com/hyperledger/burrow/core/integration"
 )
 
 // Needs to be in a _test.go file to be picked up
 func TestMain(m *testing.M) {
-	returnValue := TestWrapper(func() int {
+	returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func() int {
 		return m.Run()
 	})