diff --git a/contracts/artifacts/localnet/write_test-keypair.json b/contracts/artifacts/localnet/write_test-keypair.json
deleted file mode 100644
index dfb18e9c4..000000000
--- a/contracts/artifacts/localnet/write_test-keypair.json
+++ /dev/null
@@ -1,6 +0,0 @@
-[
-  26, 39, 164, 161, 246, 97, 149, 0, 58, 187, 146, 162, 53, 35, 107, 2, 117,
-  242, 83, 171, 48, 7, 63, 240, 69, 221, 239, 45, 97, 55, 112, 106, 192, 228,
-  214, 205, 123, 71, 58, 23, 62, 229, 166, 213, 149, 122, 96, 145, 35, 150, 16,
-  156, 247, 199, 242, 108, 173, 80, 62, 231, 39, 196, 27, 192
-]
diff --git a/integration-tests/go.sum b/integration-tests/go.sum
index af7d141c8..3aa74e79a 100644
--- a/integration-tests/go.sum
+++ b/integration-tests/go.sum
@@ -951,6 +951,8 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6
 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
 github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
 github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
+github.com/linkedin/goavro/v2 v2.12.0 h1:rIQQSj8jdAUlKQh6DttK8wCRv4t4QO09g1C4aBWXslg=
+github.com/linkedin/goavro/v2 v2.12.0/go.mod h1:KXx+erlq+RPlGSPmLF7xGo6SAbh8sCQ53x064+ioxhk=
 github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8=
 github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4=
 github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=
diff --git a/integration-tests/relayinterface/lookups_test.go b/integration-tests/relayinterface/lookups_test.go
index 1d7e9f799..1b91dc8df 100644
--- a/integration-tests/relayinterface/lookups_test.go
+++ b/integration-tests/relayinterface/lookups_test.go
@@ -1,7 +1,6 @@
 package relayinterface
 
 import (
-	"context"
 	"reflect"
 	"testing"
 	"time"
@@ -153,7 +152,7 @@ func TestPDALookups(t *testing.T) {
 			IsWritable: true,
 		}
 
-		ctx := context.Background()
+		ctx := tests.Context(t)
 		result, err := pdaLookup.Resolve(ctx, nil, nil, nil)
 		require.NoError(t, err)
 		require.Equal(t, expectedMeta, result)
@@ -184,7 +183,7 @@ func TestPDALookups(t *testing.T) {
 			IsWritable: true,
 		}
 
-		ctx := context.Background()
+		ctx := tests.Context(t)
 		args := map[string]interface{}{
 			"test_seed":    seed1,
 			"another_seed": seed2,
@@ -206,7 +205,7 @@ func TestPDALookups(t *testing.T) {
 			IsWritable: true,
 		}
 
-		ctx := context.Background()
+		ctx := tests.Context(t)
 		args := map[string]interface{}{
 			"test_seed": []byte("data"),
 		}
@@ -242,7 +241,7 @@ func TestPDALookups(t *testing.T) {
 			IsWritable: true,
 		}
 
-		ctx := context.Background()
+		ctx := tests.Context(t)
 		args := map[string]interface{}{
 			"test_seed":    seed1,
 			"another_seed": seed2,
diff --git a/pkg/solana/chainwriter/ccip_example_config.go b/pkg/solana/chainwriter/ccip_example_config.go
index 89038fd6a..acdaf3d35 100644
--- a/pkg/solana/chainwriter/ccip_example_config.go
+++ b/pkg/solana/chainwriter/ccip_example_config.go
@@ -2,8 +2,6 @@ package chainwriter
 
 import (
 	"fmt"
-
-	commoncodec "github.com/smartcontractkit/chainlink-common/pkg/codec"
 )
 
 func TestConfig() {
@@ -22,14 +20,9 @@ func TestConfig() {
 	executionReportSingleChainIDL := `{"name":"ExecutionReportSingleChain","type":{"kind":"struct","fields":[{"name":"source_chain_selector","type":"u64"},{"name":"message","type":{"defined":"Any2SolanaRampMessage"}},{"name":"root","type":{"array":["u8",32]}},{"name":"proofs","type":{"vec":{"array":["u8",32]}}}]}},{"name":"Any2SolanaRampMessage","type":{"kind":"struct","fields":[{"name":"header","type":{"defined":"RampMessageHeader"}},{"name":"sender","type":{"vec":"u8"}},{"name":"data","type":{"vec":"u8"}},{"name":"receiver","type":{"array":["u8",32]}},{"name":"extra_args","type":{"defined":"SolanaExtraArgs"}}]}},{"name":"RampMessageHeader","type":{"kind":"struct","fields":[{"name":"message_id","type":{"array":["u8",32]}},{"name":"source_chain_selector","type":"u64"},{"name":"dest_chain_selector","type":"u64"},{"name":"sequence_number","type":"u64"},{"name":"nonce","type":"u64"}]}},{"name":"SolanaExtraArgs","type":{"kind":"struct","fields":[{"name":"compute_units","type":"u32"},{"name":"allow_out_of_order_execution","type":"bool"}]}}`
 
 	executeConfig := MethodConfig{
-		FromAddress: userAddress,
-		InputModifications: commoncodec.ModifiersConfig{
-			// remove merkle root since it isn't a part of the on-chain type
-			&commoncodec.DropModifierConfig{
-				Fields: []string{"Message.ExtraArgs.MerkleRoot"},
-			},
-		},
-		ChainSpecificName: "execute",
+		FromAddress:        userAddress,
+		InputModifications: nil,
+		ChainSpecificName:  "execute",
 		// LookupTables are on-chain stores of accounts. They can be used in two ways:
 		// 1. As a way to store a list of accounts that are all associated together (i.e. Token State registry)
 		// 2. To compress the transactions in a TX and reduce the size of the TX. (The traditional way)
diff --git a/pkg/solana/chainwriter/chain_writer.go b/pkg/solana/chainwriter/chain_writer.go
index 8c82038f1..e07842201 100644
--- a/pkg/solana/chainwriter/chain_writer.go
+++ b/pkg/solana/chainwriter/chain_writer.go
@@ -251,7 +251,7 @@ func (s *SolanaChainWriterService) SubmitTransaction(ctx context.Context, contra
 	}
 
 	// Prepare transaction
-	programID, err := solana.PublicKeyFromBase58(contractName)
+	programID, err := solana.PublicKeyFromBase58(toAddress)
 	if err != nil {
 		return errorWithDebugID(fmt.Errorf("error parsing program ID: %w", err), debugID)
 	}
@@ -281,11 +281,6 @@ func (s *SolanaChainWriterService) SubmitTransaction(ctx context.Context, contra
 	return nil
 }
 
-var (
-	_ services.Service     = &SolanaChainWriterService{}
-	_ types.ContractWriter = &SolanaChainWriterService{}
-)
-
 // GetTransactionStatus returns the current status of a transaction in the underlying chain's TXM.
 func (s *SolanaChainWriterService) GetTransactionStatus(ctx context.Context, transactionID string) (types.TransactionStatus, error) {
 	return s.txm.GetTransactionStatus(ctx, transactionID)
diff --git a/pkg/solana/chainwriter/chain_writer_test.go b/pkg/solana/chainwriter/chain_writer_test.go
index 1490b519e..c7fab54e0 100644
--- a/pkg/solana/chainwriter/chain_writer_test.go
+++ b/pkg/solana/chainwriter/chain_writer_test.go
@@ -25,7 +25,7 @@ import (
 	txmMocks "github.com/smartcontractkit/chainlink-solana/pkg/solana/txm/mocks"
 )
 
-var testContractIDLJson = `{"version":"0.1.0","name":"contract_reader_interface","instructions":[{"name":"initialize","accounts":[{"name":"data","isMut":true,"isSigner":false},{"name":"signer","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"testIdx","type":"u64"},{"name":"value","type":"u64"}]},{"name":"initializeLookupTable","accounts":[{"name":"writeDataAccount","isMut":true,"isSigner":false,"docs":["PDA for LookupTableDataAccount, derived from seeds and created by the System Program"]},{"name":"admin","isMut":true,"isSigner":true,"docs":["Admin account that pays for PDA creation and signs the transaction"]},{"name":"systemProgram","isMut":false,"isSigner":false,"docs":["System Program required for PDA creation"]}],"args":[{"name":"lookupTable","type":"publicKey"}]}],"accounts":[{"name":"LookupTableDataAccount","type":{"kind":"struct","fields":[{"name":"version","type":"u8"},{"name":"administrator","type":"publicKey"},{"name":"pendingAdministrator","type":"publicKey"},{"name":"lookupTable","type":"publicKey"}]}},{"name":"DataAccount","type":{"kind":"struct","fields":[{"name":"idx","type":"u64"},{"name":"bump","type":"u8"},{"name":"u64Value","type":"u64"},{"name":"u64Slice","type":{"vec":"u64"}}]}}]}`
+var testContractIDLJson = `{"version":"0.1.0","name":"contractReaderInterface","instructions":[{"name":"initialize","accounts":[{"name":"data","isMut":true,"isSigner":false},{"name":"signer","isMut":true,"isSigner":true},{"name":"systemProgram","isMut":false,"isSigner":false}],"args":[{"name":"testIdx","type":"u64"},{"name":"value","type":"u64"}]},{"name":"initializeLookupTable","accounts":[{"name":"writeDataAccount","isMut":true,"isSigner":false,"docs":["PDA for LookupTableDataAccount, derived from seeds and created by the System Program"]},{"name":"admin","isMut":true,"isSigner":true,"docs":["Admin account that pays for PDA creation and signs the transaction"]},{"name":"systemProgram","isMut":false,"isSigner":false,"docs":["System Program required for PDA creation"]}],"args":[{"name":"lookupTable","type":"publicKey"}]}],"accounts":[{"name":"LookupTableDataAccount","type":{"kind":"struct","fields":[{"name":"version","type":"u8"},{"name":"administrator","type":"publicKey"},{"name":"pendingAdministrator","type":"publicKey"},{"name":"lookupTable","type":"publicKey"}]}},{"name":"DataAccount","type":{"kind":"struct","fields":[{"name":"idx","type":"u64"},{"name":"bump","type":"u8"},{"name":"u64Value","type":"u64"},{"name":"u64Slice","type":{"vec":"u64"}}]}}]}`
 
 func TestChainWriter_GetAddresses(t *testing.T) {
 	ctx := tests.Context(t)
@@ -401,7 +401,7 @@ func TestChainWriter_SubmitTransaction(t *testing.T) {
 
 	// create lookup table addresses
 	seed2 := []byte("seed2")
-	programID := chainwriter.GetRandomPubKey(t)
+	programID := solana.MustPublicKeyFromBase58("6AfuXF6HapDUhQfE4nQG9C1SGtA1YjP3icaJyRfU4RyE")
 	derivedTablePda := mustFindPdaProgramAddress(t, [][]byte{seed2}, programID)
 	// mock data account response from program
 	derivedLookupTablePubkey := mockDataAccountLookupTable(t, rw, derivedTablePda)
@@ -416,7 +416,7 @@ func TestChainWriter_SubmitTransaction(t *testing.T) {
 
 	cwConfig := chainwriter.ChainWriterConfig{
 		Programs: map[string]chainwriter.ProgramConfig{
-			"6AfuXF6HapDUhQfE4nQG9C1SGtA1YjP3icaJyRfU4RyE": {
+			"contractReaderInterface": {
 				Methods: map[string]chainwriter.MethodConfig{
 					"initializeLookupTable": {
 						FromAddress:       admin.String(),
@@ -505,21 +505,21 @@ func TestChainWriter_SubmitTransaction(t *testing.T) {
 	t.Run("fails to encode payload if args with missing values provided", func(t *testing.T) {
 		txID := uuid.NewString()
 		args := map[string]interface{}{}
-		submitErr := cw.SubmitTransaction(ctx, "6AfuXF6HapDUhQfE4nQG9C1SGtA1YjP3icaJyRfU4RyE", "initializeLookupTable", args, txID, programID.String(), nil, nil)
+		submitErr := cw.SubmitTransaction(ctx, "contractReaderInterface", "initializeLookupTable", args, txID, programID.String(), nil, nil)
 		require.Error(t, submitErr)
 	})
 
 	t.Run("fails if invalid contract name provided", func(t *testing.T) {
 		txID := uuid.NewString()
 		args := map[string]interface{}{}
-		submitErr := cw.SubmitTransaction(ctx, "contract_reader_interface", "initializeLookupTable", args, txID, programID.String(), nil, nil)
+		submitErr := cw.SubmitTransaction(ctx, "badContract", "initializeLookupTable", args, txID, programID.String(), nil, nil)
 		require.Error(t, submitErr)
 	})
 
 	t.Run("fails if invalid method provided", func(t *testing.T) {
 		txID := uuid.NewString()
 		args := map[string]interface{}{}
-		submitErr := cw.SubmitTransaction(ctx, "6AfuXF6HapDUhQfE4nQG9C1SGtA1YjP3icaJyRfU4RyE", "badMethod", args, txID, programID.String(), nil, nil)
+		submitErr := cw.SubmitTransaction(ctx, "contractReaderInterface", "badMethod", args, txID, programID.String(), nil, nil)
 		require.Error(t, submitErr)
 	})
 
@@ -527,7 +527,6 @@ func TestChainWriter_SubmitTransaction(t *testing.T) {
 		recentBlockHash := solana.Hash{}
 		rw.On("LatestBlockhash", mock.Anything).Return(&rpc.GetLatestBlockhashResult{Value: &rpc.LatestBlockhashResult{Blockhash: recentBlockHash, LastValidBlockHeight: uint64(100)}}, nil).Once()
 		txID := uuid.NewString()
-		configProgramID := solana.MustPublicKeyFromBase58("6AfuXF6HapDUhQfE4nQG9C1SGtA1YjP3icaJyRfU4RyE")
 
 		txm.On("Enqueue", mock.Anything, account1.String(), mock.MatchedBy(func(tx *solana.Transaction) bool {
 			// match transaction fields to ensure it was built as expected
@@ -538,7 +537,7 @@ func TestChainWriter_SubmitTransaction(t *testing.T) {
 			require.Equal(t, account1, tx.Message.AccountKeys[1])                                    // account constant
 			require.Equal(t, account2, tx.Message.AccountKeys[2])                                    // account lookup
 			require.Equal(t, account3, tx.Message.AccountKeys[3])                                    // pda lookup
-			require.Equal(t, configProgramID, tx.Message.AccountKeys[4])                             // instruction program ID
+			require.Equal(t, programID, tx.Message.AccountKeys[4])                                   // instruction program ID
 			require.Len(t, tx.Message.AddressTableLookups, 1)                                        // address table look contains entry
 			require.Equal(t, derivedLookupTablePubkey, tx.Message.AddressTableLookups[0].AccountKey) // address table
 			return true
@@ -550,7 +549,7 @@ func TestChainWriter_SubmitTransaction(t *testing.T) {
 			"seed1":        seed1,
 			"seed2":        seed2,
 		}
-		submitErr := cw.SubmitTransaction(ctx, "6AfuXF6HapDUhQfE4nQG9C1SGtA1YjP3icaJyRfU4RyE", "initializeLookupTable", args, txID, programID.String(), nil, nil)
+		submitErr := cw.SubmitTransaction(ctx, "contractReaderInterface", "initializeLookupTable", args, txID, programID.String(), nil, nil)
 		require.NoError(t, submitErr)
 	})
 }
diff --git a/pkg/solana/chainwriter/helpers.go b/pkg/solana/chainwriter/helpers.go
index 22a2d1c67..8b7276276 100644
--- a/pkg/solana/chainwriter/helpers.go
+++ b/pkg/solana/chainwriter/helpers.go
@@ -56,7 +56,7 @@ func GetValuesAtLocation(args any, location string) ([][]byte, error) {
 }
 
 func GetDebugIDAtLocation(args any, location string) (string, error) {
-	debugIDList, err := GetValueAtLocation(args, location)
+	debugIDList, err := GetValuesAtLocation(args, location)
 	if err != nil {
 		return "", err
 	}
@@ -67,26 +67,6 @@ func GetDebugIDAtLocation(args any, location string) (string, error) {
 	return debugID, nil
 }
 
-func GetValueAtLocation(args any, location string) ([][]byte, error) {
-	path := strings.Split(location, ".")
-
-	valueList, err := traversePath(args, path)
-	if err != nil {
-		return nil, err
-	}
-
-	var values [][]byte
-	for _, value := range valueList {
-		byteArray, ok := value.([]byte)
-		if !ok {
-			return nil, fmt.Errorf("invalid value format at path: %s", location)
-		}
-		values = append(values, byteArray)
-	}
-
-	return values, nil
-}
-
 func errorWithDebugID(err error, debugID string) error {
 	if debugID == "" {
 		return err
diff --git a/pkg/solana/chainwriter/lookups.go b/pkg/solana/chainwriter/lookups.go
index 37de7a567..7f2b45afe 100644
--- a/pkg/solana/chainwriter/lookups.go
+++ b/pkg/solana/chainwriter/lookups.go
@@ -212,6 +212,7 @@ func decodeBorshIntoType(data []byte, typ reflect.Type) (interface{}, error) {
 // It handles both AddressSeeds (which are public keys) and ValueSeeds (which are byte arrays from input args).
 func getSeedBytes(ctx context.Context, lookup PDALookups, args any, derivedTableMap map[string]map[string][]*solana.AccountMeta, reader client.Reader) ([][]byte, error) {
 	var seedBytes [][]byte
+	maxSeedLength := 32
 
 	for _, seed := range lookup.Seeds {
 		if lookupSeed, ok := seed.(AccountLookup); ok {
@@ -220,7 +221,13 @@ func getSeedBytes(ctx context.Context, lookup PDALookups, args any, derivedTable
 			if err != nil {
 				return nil, fmt.Errorf("error getting address seed: %w", err)
 			}
-			seedBytes = append(seedBytes, bytes...)
+			// validate seed length
+			for _, b := range bytes {
+				if len(b) > maxSeedLength {
+					return nil, fmt.Errorf("seed byte array exceeds maximum length of %d: got %d bytes", maxSeedLength, len(b))
+				}
+				seedBytes = append(seedBytes, b)
+			}
 		} else {
 			// Get address seeds from the lookup
 			seedAddresses, err := GetAddresses(ctx, args, []Lookup{seed}, derivedTableMap, reader)
@@ -240,10 +247,9 @@ func getSeedBytes(ctx context.Context, lookup PDALookups, args any, derivedTable
 
 // generatePDAs generates program-derived addresses (PDAs) from public keys and seeds.
 func generatePDAs(publicKeys []*solana.AccountMeta, seeds [][]byte, lookup PDALookups) ([]*solana.AccountMeta, error) {
-	if len(seeds) > 1 && len(publicKeys) > 1 {
-		return nil, fmt.Errorf("multiple public keys and multiple seeds are not allowed")
+	if len(seeds) > 16 {
+		return nil, fmt.Errorf("seed maximum exceeded: %d", len(seeds))
 	}
-
 	var addresses []*solana.AccountMeta
 	for _, publicKeyMeta := range publicKeys {
 		address, _, err := solana.FindProgramAddress(seeds, publicKeyMeta.PublicKey)