Browse Source

node: commit proto and matching test fixes #1769

Evan Gray 3 năm trước cách đây
mục cha
commit
f60e6669ec

+ 5 - 0
.github/workflows/build.yml

@@ -264,6 +264,11 @@ jobs:
       # The go-ethereum and celo-blockchain packages both implement secp256k1 using the exact same header, but that causes duplicate symbols.
       - name: Run golang tests
         run: cd node && go test -v -race -ldflags '-extldflags "-Wl,--allow-multiple-definition" ' ./...
+      - name: Ensure generated proto matches
+        run: |
+          rm -rf node/pkg/proto
+          docker build --target go-export -f Dockerfile.proto -o type=local,dest=node .
+          git diff --name-only --exit-code && echo "✅ Generated proto matches committed proto" || (echo "❌ Generated proto differs from committed proto, run \`rm -rf node/pkg/proto && docker build --target go-export -f Dockerfile.proto -o type=local,dest=node .\` and commit the result" >&2 && exit 1)
 
   # Run Rust lints and tests
   rust-lint-and-tests:

+ 6 - 20
Tiltfile

@@ -90,20 +90,6 @@ if not ci:
 def k8s_yaml_with_ns(objects):
     return k8s_yaml(namespace_inject(objects, namespace))
 
-# protos
-
-proto_deps = ["./proto", "buf.yaml", "buf.gen.yaml"]
-
-local_resource(
-    name = "proto-gen",
-    deps = proto_deps,
-    cmd = "tilt docker build -- --target go-export -f Dockerfile.proto -o type=local,dest=node .",
-    env = {"DOCKER_BUILDKIT": "1"},
-    labels = ["protobuf"],
-    allow_parallel = True,
-    trigger_mode = trigger_mode,
-)
-
 local_resource(
     name = "const-gen",
     deps = ["scripts", "clients", "ethereum/.env.test"],
@@ -263,7 +249,7 @@ def build_node_yaml():
 
 k8s_yaml_with_ns(build_node_yaml())
 
-guardian_resource_deps = ["proto-gen", "eth-devnet"]
+guardian_resource_deps = ["eth-devnet"]
 if evm2:
     guardian_resource_deps = guardian_resource_deps + ["eth-devnet2"]
 if solana:
@@ -351,7 +337,7 @@ k8s_yaml_with_ns("devnet/spy.yaml")
 
 k8s_resource(
     "spy",
-    resource_deps = ["proto-gen", "guardian"],
+    resource_deps = ["guardian"],
     port_forwards = [
         port_forward(6061, container_port = 6060, name = "Debug/Status Server [:6061]", host = webHost),
         port_forward(7072, name = "Spy gRPC [:7072]", host = webHost),
@@ -448,7 +434,7 @@ if spy_relayer:
 
     k8s_resource(
         "spy-listener",
-        resource_deps = ["proto-gen", "guardian", "redis", "spy"],
+        resource_deps = ["guardian", "redis", "spy"],
         port_forwards = [
             port_forward(6062, container_port = 6060, name = "Debug/Status Server [:6062]", host = webHost),
             port_forward(4201, name = "REST [:4201]", host = webHost),
@@ -462,7 +448,7 @@ if spy_relayer:
 
     k8s_resource(
         "spy-relayer",
-        resource_deps = ["proto-gen", "guardian", "redis"],
+        resource_deps = ["guardian", "redis"],
         port_forwards = [
             port_forward(8083, name = "Prometheus [:8083]", host = webHost),
         ],
@@ -474,7 +460,7 @@ if spy_relayer:
 
     k8s_resource(
         "spy-wallet-monitor",
-        resource_deps = ["proto-gen", "guardian", "redis"],
+        resource_deps = ["guardian", "redis"],
         port_forwards = [
             port_forward(8084, name = "Prometheus [:8084]", host = webHost),
         ],
@@ -573,7 +559,7 @@ if explorer:
     )
     k8s_resource(
         "cloud-functions",
-        resource_deps = ["proto-gen", "bigtable-emulator", "pubsub-emulator"],
+        resource_deps = ["bigtable-emulator", "pubsub-emulator"],
         port_forwards = [port_forward(8090, name = "Cloud Functions [:8090]", host = webHost)],
         labels = ["explorer"],
         trigger_mode = trigger_mode,

+ 0 - 1
node/pkg/.gitignore

@@ -1 +0,0 @@
-proto

+ 2011 - 0
node/pkg/proto/gossip/v1/gossip.pb.go

@@ -0,0 +1,2011 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.27.1
+// 	protoc        (unknown)
+// source: gossip/v1/gossip.proto
+
+package gossipv1
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type GossipMessage struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to Message:
+	//	*GossipMessage_SignedObservation
+	//	*GossipMessage_SignedHeartbeat
+	//	*GossipMessage_SignedVaaWithQuorum
+	//	*GossipMessage_SignedObservationRequest
+	//	*GossipMessage_SignedBatchObservation
+	//	*GossipMessage_SignedBatchVaaWithQuorum
+	//	*GossipMessage_SignedChainGovernorConfig
+	//	*GossipMessage_SignedChainGovernorStatus
+	Message isGossipMessage_Message `protobuf_oneof:"message"`
+}
+
+func (x *GossipMessage) Reset() {
+	*x = GossipMessage{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GossipMessage) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GossipMessage) ProtoMessage() {}
+
+func (x *GossipMessage) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GossipMessage.ProtoReflect.Descriptor instead.
+func (*GossipMessage) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{0}
+}
+
+func (m *GossipMessage) GetMessage() isGossipMessage_Message {
+	if m != nil {
+		return m.Message
+	}
+	return nil
+}
+
+func (x *GossipMessage) GetSignedObservation() *SignedObservation {
+	if x, ok := x.GetMessage().(*GossipMessage_SignedObservation); ok {
+		return x.SignedObservation
+	}
+	return nil
+}
+
+func (x *GossipMessage) GetSignedHeartbeat() *SignedHeartbeat {
+	if x, ok := x.GetMessage().(*GossipMessage_SignedHeartbeat); ok {
+		return x.SignedHeartbeat
+	}
+	return nil
+}
+
+func (x *GossipMessage) GetSignedVaaWithQuorum() *SignedVAAWithQuorum {
+	if x, ok := x.GetMessage().(*GossipMessage_SignedVaaWithQuorum); ok {
+		return x.SignedVaaWithQuorum
+	}
+	return nil
+}
+
+func (x *GossipMessage) GetSignedObservationRequest() *SignedObservationRequest {
+	if x, ok := x.GetMessage().(*GossipMessage_SignedObservationRequest); ok {
+		return x.SignedObservationRequest
+	}
+	return nil
+}
+
+func (x *GossipMessage) GetSignedBatchObservation() *SignedBatchObservation {
+	if x, ok := x.GetMessage().(*GossipMessage_SignedBatchObservation); ok {
+		return x.SignedBatchObservation
+	}
+	return nil
+}
+
+func (x *GossipMessage) GetSignedBatchVaaWithQuorum() *SignedBatchVAAWithQuorum {
+	if x, ok := x.GetMessage().(*GossipMessage_SignedBatchVaaWithQuorum); ok {
+		return x.SignedBatchVaaWithQuorum
+	}
+	return nil
+}
+
+func (x *GossipMessage) GetSignedChainGovernorConfig() *SignedChainGovernorConfig {
+	if x, ok := x.GetMessage().(*GossipMessage_SignedChainGovernorConfig); ok {
+		return x.SignedChainGovernorConfig
+	}
+	return nil
+}
+
+func (x *GossipMessage) GetSignedChainGovernorStatus() *SignedChainGovernorStatus {
+	if x, ok := x.GetMessage().(*GossipMessage_SignedChainGovernorStatus); ok {
+		return x.SignedChainGovernorStatus
+	}
+	return nil
+}
+
+type isGossipMessage_Message interface {
+	isGossipMessage_Message()
+}
+
+type GossipMessage_SignedObservation struct {
+	SignedObservation *SignedObservation `protobuf:"bytes,2,opt,name=signed_observation,json=signedObservation,proto3,oneof"`
+}
+
+type GossipMessage_SignedHeartbeat struct {
+	SignedHeartbeat *SignedHeartbeat `protobuf:"bytes,3,opt,name=signed_heartbeat,json=signedHeartbeat,proto3,oneof"`
+}
+
+type GossipMessage_SignedVaaWithQuorum struct {
+	SignedVaaWithQuorum *SignedVAAWithQuorum `protobuf:"bytes,4,opt,name=signed_vaa_with_quorum,json=signedVaaWithQuorum,proto3,oneof"`
+}
+
+type GossipMessage_SignedObservationRequest struct {
+	SignedObservationRequest *SignedObservationRequest `protobuf:"bytes,5,opt,name=signed_observation_request,json=signedObservationRequest,proto3,oneof"`
+}
+
+type GossipMessage_SignedBatchObservation struct {
+	SignedBatchObservation *SignedBatchObservation `protobuf:"bytes,6,opt,name=signed_batch_observation,json=signedBatchObservation,proto3,oneof"`
+}
+
+type GossipMessage_SignedBatchVaaWithQuorum struct {
+	SignedBatchVaaWithQuorum *SignedBatchVAAWithQuorum `protobuf:"bytes,7,opt,name=signed_batch_vaa_with_quorum,json=signedBatchVaaWithQuorum,proto3,oneof"`
+}
+
+type GossipMessage_SignedChainGovernorConfig struct {
+	SignedChainGovernorConfig *SignedChainGovernorConfig `protobuf:"bytes,8,opt,name=signed_chain_governor_config,json=signedChainGovernorConfig,proto3,oneof"`
+}
+
+type GossipMessage_SignedChainGovernorStatus struct {
+	SignedChainGovernorStatus *SignedChainGovernorStatus `protobuf:"bytes,9,opt,name=signed_chain_governor_status,json=signedChainGovernorStatus,proto3,oneof"`
+}
+
+func (*GossipMessage_SignedObservation) isGossipMessage_Message() {}
+
+func (*GossipMessage_SignedHeartbeat) isGossipMessage_Message() {}
+
+func (*GossipMessage_SignedVaaWithQuorum) isGossipMessage_Message() {}
+
+func (*GossipMessage_SignedObservationRequest) isGossipMessage_Message() {}
+
+func (*GossipMessage_SignedBatchObservation) isGossipMessage_Message() {}
+
+func (*GossipMessage_SignedBatchVaaWithQuorum) isGossipMessage_Message() {}
+
+func (*GossipMessage_SignedChainGovernorConfig) isGossipMessage_Message() {}
+
+func (*GossipMessage_SignedChainGovernorStatus) isGossipMessage_Message() {}
+
+type SignedHeartbeat struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Serialized Heartbeat message.
+	Heartbeat []byte `protobuf:"bytes,1,opt,name=heartbeat,proto3" json:"heartbeat,omitempty"`
+	// ECDSA signature using the node's guardian public key.
+	Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
+	// Guardian address that signed this payload (truncated Eth address).
+	// This is already contained in Heartbeat, however, we want to verify
+	// the payload before we deserialize it.
+	GuardianAddr []byte `protobuf:"bytes,3,opt,name=guardian_addr,json=guardianAddr,proto3" json:"guardian_addr,omitempty"`
+}
+
+func (x *SignedHeartbeat) Reset() {
+	*x = SignedHeartbeat{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SignedHeartbeat) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SignedHeartbeat) ProtoMessage() {}
+
+func (x *SignedHeartbeat) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SignedHeartbeat.ProtoReflect.Descriptor instead.
+func (*SignedHeartbeat) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *SignedHeartbeat) GetHeartbeat() []byte {
+	if x != nil {
+		return x.Heartbeat
+	}
+	return nil
+}
+
+func (x *SignedHeartbeat) GetSignature() []byte {
+	if x != nil {
+		return x.Signature
+	}
+	return nil
+}
+
+func (x *SignedHeartbeat) GetGuardianAddr() []byte {
+	if x != nil {
+		return x.GuardianAddr
+	}
+	return nil
+}
+
+// P2P gossip heartbeats for network introspection purposes.
+type Heartbeat struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The node's arbitrarily chosen, untrusted nodeName.
+	NodeName string `protobuf:"bytes,1,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`
+	// A monotonic counter that resets to zero on startup.
+	Counter int64 `protobuf:"varint,2,opt,name=counter,proto3" json:"counter,omitempty"`
+	// UNIX wall time.
+	Timestamp int64                `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	Networks  []*Heartbeat_Network `protobuf:"bytes,4,rep,name=networks,proto3" json:"networks,omitempty"`
+	// Human-readable representation of the current bridge node release.
+	Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"`
+	// Human-readable representation of the guardian key's address.
+	GuardianAddr string `protobuf:"bytes,6,opt,name=guardian_addr,json=guardianAddr,proto3" json:"guardian_addr,omitempty"`
+	// UNIX boot timestamp.
+	BootTimestamp int64 `protobuf:"varint,7,opt,name=boot_timestamp,json=bootTimestamp,proto3" json:"boot_timestamp,omitempty"`
+	// List of features enabled on this node.
+	Features []string `protobuf:"bytes,8,rep,name=features,proto3" json:"features,omitempty"`
+}
+
+func (x *Heartbeat) Reset() {
+	*x = Heartbeat{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Heartbeat) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Heartbeat) ProtoMessage() {}
+
+func (x *Heartbeat) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Heartbeat.ProtoReflect.Descriptor instead.
+func (*Heartbeat) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Heartbeat) GetNodeName() string {
+	if x != nil {
+		return x.NodeName
+	}
+	return ""
+}
+
+func (x *Heartbeat) GetCounter() int64 {
+	if x != nil {
+		return x.Counter
+	}
+	return 0
+}
+
+func (x *Heartbeat) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *Heartbeat) GetNetworks() []*Heartbeat_Network {
+	if x != nil {
+		return x.Networks
+	}
+	return nil
+}
+
+func (x *Heartbeat) GetVersion() string {
+	if x != nil {
+		return x.Version
+	}
+	return ""
+}
+
+func (x *Heartbeat) GetGuardianAddr() string {
+	if x != nil {
+		return x.GuardianAddr
+	}
+	return ""
+}
+
+func (x *Heartbeat) GetBootTimestamp() int64 {
+	if x != nil {
+		return x.BootTimestamp
+	}
+	return 0
+}
+
+func (x *Heartbeat) GetFeatures() []string {
+	if x != nil {
+		return x.Features
+	}
+	return nil
+}
+
+// A SignedObservation is a signed statement by a given guardian node
+// that they observed a given event.
+//
+// Observations always result from an external, final event being observed.
+// Examples are emitted messages in finalized blocks on a block or guardian set changes
+// injected by node operators after reaching off-chain consensus.
+//
+// The event is uniquely identified by its hashed (tx_hash, nonce, values...) tuple.
+//
+// Other nodes will verify the signature. Once any node has observed a quorum of
+// guardians submitting valid signatures for a given hash, they can be assembled into a VAA.
+//
+// Messages without valid signature are dropped unceremoniously.
+type SignedObservation struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Guardian pubkey as truncated eth address.
+	Addr []byte `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
+	// The observation's deterministic, unique hash.
+	Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"`
+	// ECSDA signature of the hash using the node's guardian key.
+	Signature []byte `protobuf:"bytes,3,opt,name=signature,proto3" json:"signature,omitempty"`
+	// Transaction hash this observation was made from.
+	// Optional, included for observability.
+	TxHash []byte `protobuf:"bytes,4,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"`
+	// Message ID (chain/emitter/seq) for this observation.
+	// Optional, included for observability.
+	MessageId string `protobuf:"bytes,5,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"`
+}
+
+func (x *SignedObservation) Reset() {
+	*x = SignedObservation{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SignedObservation) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SignedObservation) ProtoMessage() {}
+
+func (x *SignedObservation) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SignedObservation.ProtoReflect.Descriptor instead.
+func (*SignedObservation) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *SignedObservation) GetAddr() []byte {
+	if x != nil {
+		return x.Addr
+	}
+	return nil
+}
+
+func (x *SignedObservation) GetHash() []byte {
+	if x != nil {
+		return x.Hash
+	}
+	return nil
+}
+
+func (x *SignedObservation) GetSignature() []byte {
+	if x != nil {
+		return x.Signature
+	}
+	return nil
+}
+
+func (x *SignedObservation) GetTxHash() []byte {
+	if x != nil {
+		return x.TxHash
+	}
+	return nil
+}
+
+func (x *SignedObservation) GetMessageId() string {
+	if x != nil {
+		return x.MessageId
+	}
+	return ""
+}
+
+// A SignedVAAWithQuorum message is sent by nodes whenever one of the VAAs they observed
+// reached a 2/3+ quorum to be considered valid. Signed VAAs are broadcasted to the gossip
+// network to allow nodes to persist them even if they failed to observe the signature.
+type SignedVAAWithQuorum struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Vaa []byte `protobuf:"bytes,1,opt,name=vaa,proto3" json:"vaa,omitempty"`
+}
+
+func (x *SignedVAAWithQuorum) Reset() {
+	*x = SignedVAAWithQuorum{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SignedVAAWithQuorum) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SignedVAAWithQuorum) ProtoMessage() {}
+
+func (x *SignedVAAWithQuorum) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SignedVAAWithQuorum.ProtoReflect.Descriptor instead.
+func (*SignedVAAWithQuorum) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *SignedVAAWithQuorum) GetVaa() []byte {
+	if x != nil {
+		return x.Vaa
+	}
+	return nil
+}
+
+// Any guardian can send a SignedObservationRequest to the network to request
+// all guardians to re-observe a given transaction. This is rate-limited to one
+// request per second per guardian to prevent abuse.
+//
+// In the current implementation, this is only implemented for Solana.
+// For Solana, the tx_hash is the account address of the transaction's message account.
+type SignedObservationRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Serialized observation request.
+	ObservationRequest []byte `protobuf:"bytes,1,opt,name=observation_request,json=observationRequest,proto3" json:"observation_request,omitempty"`
+	// Signature
+	Signature    []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
+	GuardianAddr []byte `protobuf:"bytes,3,opt,name=guardian_addr,json=guardianAddr,proto3" json:"guardian_addr,omitempty"`
+}
+
+func (x *SignedObservationRequest) Reset() {
+	*x = SignedObservationRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SignedObservationRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SignedObservationRequest) ProtoMessage() {}
+
+func (x *SignedObservationRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SignedObservationRequest.ProtoReflect.Descriptor instead.
+func (*SignedObservationRequest) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *SignedObservationRequest) GetObservationRequest() []byte {
+	if x != nil {
+		return x.ObservationRequest
+	}
+	return nil
+}
+
+func (x *SignedObservationRequest) GetSignature() []byte {
+	if x != nil {
+		return x.Signature
+	}
+	return nil
+}
+
+func (x *SignedObservationRequest) GetGuardianAddr() []byte {
+	if x != nil {
+		return x.GuardianAddr
+	}
+	return nil
+}
+
+type ObservationRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ChainId uint32 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
+	TxHash  []byte `protobuf:"bytes,2,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"`
+}
+
+func (x *ObservationRequest) Reset() {
+	*x = ObservationRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ObservationRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ObservationRequest) ProtoMessage() {}
+
+func (x *ObservationRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ObservationRequest.ProtoReflect.Descriptor instead.
+func (*ObservationRequest) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *ObservationRequest) GetChainId() uint32 {
+	if x != nil {
+		return x.ChainId
+	}
+	return 0
+}
+
+func (x *ObservationRequest) GetTxHash() []byte {
+	if x != nil {
+		return x.TxHash
+	}
+	return nil
+}
+
+// A SignedBatchObservation is a signed statement by a given guardian node
+// that they observed a series of messages originating from a transaction.
+//
+// BatcheObervations are emitted when all the Observations from a tx reach quorum.
+//
+// The event is uniquely identified by its hash (made from hashing all the
+// individual Observation hashes).
+//
+// Messages without valid signature are dropped unceremoniously.
+type SignedBatchObservation struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Guardian pubkey as truncated eth address.
+	Addr []byte `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
+	// The observation batch's deterministic, unique hash.
+	Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"`
+	// ECSDA signature of the hash using the node's guardian key.
+	Signature []byte `protobuf:"bytes,3,opt,name=signature,proto3" json:"signature,omitempty"`
+	// Transaction hash this observation was made from.
+	TxHash []byte `protobuf:"bytes,4,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"`
+	// Chain ID for this observation.
+	ChainId uint32 `protobuf:"varint,5,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
+	// Batch ID - emitterChain/transactionID
+	BatchId string `protobuf:"bytes,6,opt,name=batch_id,json=batchId,proto3" json:"batch_id,omitempty"`
+}
+
+func (x *SignedBatchObservation) Reset() {
+	*x = SignedBatchObservation{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SignedBatchObservation) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SignedBatchObservation) ProtoMessage() {}
+
+func (x *SignedBatchObservation) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SignedBatchObservation.ProtoReflect.Descriptor instead.
+func (*SignedBatchObservation) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *SignedBatchObservation) GetAddr() []byte {
+	if x != nil {
+		return x.Addr
+	}
+	return nil
+}
+
+func (x *SignedBatchObservation) GetHash() []byte {
+	if x != nil {
+		return x.Hash
+	}
+	return nil
+}
+
+func (x *SignedBatchObservation) GetSignature() []byte {
+	if x != nil {
+		return x.Signature
+	}
+	return nil
+}
+
+func (x *SignedBatchObservation) GetTxHash() []byte {
+	if x != nil {
+		return x.TxHash
+	}
+	return nil
+}
+
+func (x *SignedBatchObservation) GetChainId() uint32 {
+	if x != nil {
+		return x.ChainId
+	}
+	return 0
+}
+
+func (x *SignedBatchObservation) GetBatchId() string {
+	if x != nil {
+		return x.BatchId
+	}
+	return ""
+}
+
+type SignedBatchVAAWithQuorum struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	BatchVaa []byte `protobuf:"bytes,1,opt,name=batch_vaa,json=batchVaa,proto3" json:"batch_vaa,omitempty"`
+}
+
+func (x *SignedBatchVAAWithQuorum) Reset() {
+	*x = SignedBatchVAAWithQuorum{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SignedBatchVAAWithQuorum) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SignedBatchVAAWithQuorum) ProtoMessage() {}
+
+func (x *SignedBatchVAAWithQuorum) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SignedBatchVAAWithQuorum.ProtoReflect.Descriptor instead.
+func (*SignedBatchVAAWithQuorum) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *SignedBatchVAAWithQuorum) GetBatchVaa() []byte {
+	if x != nil {
+		return x.BatchVaa
+	}
+	return nil
+}
+
+// This message is published every five minutes.
+type SignedChainGovernorConfig struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Serialized ChainGovernorConfig message.
+	Config []byte `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
+	// ECDSA signature using the node's guardian key.
+	Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
+	// Guardian address that signed this payload (truncated Eth address).
+	GuardianAddr []byte `protobuf:"bytes,3,opt,name=guardian_addr,json=guardianAddr,proto3" json:"guardian_addr,omitempty"`
+}
+
+func (x *SignedChainGovernorConfig) Reset() {
+	*x = SignedChainGovernorConfig{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SignedChainGovernorConfig) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SignedChainGovernorConfig) ProtoMessage() {}
+
+func (x *SignedChainGovernorConfig) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SignedChainGovernorConfig.ProtoReflect.Descriptor instead.
+func (*SignedChainGovernorConfig) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *SignedChainGovernorConfig) GetConfig() []byte {
+	if x != nil {
+		return x.Config
+	}
+	return nil
+}
+
+func (x *SignedChainGovernorConfig) GetSignature() []byte {
+	if x != nil {
+		return x.Signature
+	}
+	return nil
+}
+
+func (x *SignedChainGovernorConfig) GetGuardianAddr() []byte {
+	if x != nil {
+		return x.GuardianAddr
+	}
+	return nil
+}
+
+type ChainGovernorConfig struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	NodeName  string                       `protobuf:"bytes,1,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`
+	Counter   int64                        `protobuf:"varint,2,opt,name=counter,proto3" json:"counter,omitempty"`
+	Timestamp int64                        `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	Chains    []*ChainGovernorConfig_Chain `protobuf:"bytes,4,rep,name=chains,proto3" json:"chains,omitempty"`
+	Tokens    []*ChainGovernorConfig_Token `protobuf:"bytes,5,rep,name=tokens,proto3" json:"tokens,omitempty"`
+}
+
+func (x *ChainGovernorConfig) Reset() {
+	*x = ChainGovernorConfig{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[10]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorConfig) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorConfig) ProtoMessage() {}
+
+func (x *ChainGovernorConfig) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[10]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorConfig.ProtoReflect.Descriptor instead.
+func (*ChainGovernorConfig) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *ChainGovernorConfig) GetNodeName() string {
+	if x != nil {
+		return x.NodeName
+	}
+	return ""
+}
+
+func (x *ChainGovernorConfig) GetCounter() int64 {
+	if x != nil {
+		return x.Counter
+	}
+	return 0
+}
+
+func (x *ChainGovernorConfig) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *ChainGovernorConfig) GetChains() []*ChainGovernorConfig_Chain {
+	if x != nil {
+		return x.Chains
+	}
+	return nil
+}
+
+func (x *ChainGovernorConfig) GetTokens() []*ChainGovernorConfig_Token {
+	if x != nil {
+		return x.Tokens
+	}
+	return nil
+}
+
+// This message is published every minute.
+type SignedChainGovernorStatus struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Serialized ChainGovernorStatus message.
+	Status []byte `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
+	// ECDSA signature using the node's guardian key.
+	Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
+	// Guardian address that signed this payload (truncated Eth address).
+	GuardianAddr []byte `protobuf:"bytes,3,opt,name=guardian_addr,json=guardianAddr,proto3" json:"guardian_addr,omitempty"`
+}
+
+func (x *SignedChainGovernorStatus) Reset() {
+	*x = SignedChainGovernorStatus{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SignedChainGovernorStatus) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SignedChainGovernorStatus) ProtoMessage() {}
+
+func (x *SignedChainGovernorStatus) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SignedChainGovernorStatus.ProtoReflect.Descriptor instead.
+func (*SignedChainGovernorStatus) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *SignedChainGovernorStatus) GetStatus() []byte {
+	if x != nil {
+		return x.Status
+	}
+	return nil
+}
+
+func (x *SignedChainGovernorStatus) GetSignature() []byte {
+	if x != nil {
+		return x.Signature
+	}
+	return nil
+}
+
+func (x *SignedChainGovernorStatus) GetGuardianAddr() []byte {
+	if x != nil {
+		return x.GuardianAddr
+	}
+	return nil
+}
+
+type ChainGovernorStatus struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	NodeName  string                       `protobuf:"bytes,1,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`
+	Counter   int64                        `protobuf:"varint,2,opt,name=counter,proto3" json:"counter,omitempty"`
+	Timestamp int64                        `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	Chains    []*ChainGovernorStatus_Chain `protobuf:"bytes,4,rep,name=chains,proto3" json:"chains,omitempty"`
+}
+
+func (x *ChainGovernorStatus) Reset() {
+	*x = ChainGovernorStatus{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorStatus) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorStatus) ProtoMessage() {}
+
+func (x *ChainGovernorStatus) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorStatus.ProtoReflect.Descriptor instead.
+func (*ChainGovernorStatus) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *ChainGovernorStatus) GetNodeName() string {
+	if x != nil {
+		return x.NodeName
+	}
+	return ""
+}
+
+func (x *ChainGovernorStatus) GetCounter() int64 {
+	if x != nil {
+		return x.Counter
+	}
+	return 0
+}
+
+func (x *ChainGovernorStatus) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *ChainGovernorStatus) GetChains() []*ChainGovernorStatus_Chain {
+	if x != nil {
+		return x.Chains
+	}
+	return nil
+}
+
+type Heartbeat_Network struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Canonical chain ID.
+	Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+	// Consensus height of the node.
+	Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
+	// Chain-specific human-readable representation of the bridge contract address.
+	ContractAddress string `protobuf:"bytes,3,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"`
+	// Connection error count
+	ErrorCount uint64 `protobuf:"varint,4,opt,name=error_count,json=errorCount,proto3" json:"error_count,omitempty"`
+}
+
+func (x *Heartbeat_Network) Reset() {
+	*x = Heartbeat_Network{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Heartbeat_Network) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Heartbeat_Network) ProtoMessage() {}
+
+func (x *Heartbeat_Network) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Heartbeat_Network.ProtoReflect.Descriptor instead.
+func (*Heartbeat_Network) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{2, 0}
+}
+
+func (x *Heartbeat_Network) GetId() uint32 {
+	if x != nil {
+		return x.Id
+	}
+	return 0
+}
+
+func (x *Heartbeat_Network) GetHeight() int64 {
+	if x != nil {
+		return x.Height
+	}
+	return 0
+}
+
+func (x *Heartbeat_Network) GetContractAddress() string {
+	if x != nil {
+		return x.ContractAddress
+	}
+	return ""
+}
+
+func (x *Heartbeat_Network) GetErrorCount() uint64 {
+	if x != nil {
+		return x.ErrorCount
+	}
+	return 0
+}
+
+type ChainGovernorConfig_Chain struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ChainId            uint32 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
+	NotionalLimit      uint64 `protobuf:"varint,2,opt,name=notional_limit,json=notionalLimit,proto3" json:"notional_limit,omitempty"`
+	BigTransactionSize uint64 `protobuf:"varint,3,opt,name=big_transaction_size,json=bigTransactionSize,proto3" json:"big_transaction_size,omitempty"`
+}
+
+func (x *ChainGovernorConfig_Chain) Reset() {
+	*x = ChainGovernorConfig_Chain{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorConfig_Chain) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorConfig_Chain) ProtoMessage() {}
+
+func (x *ChainGovernorConfig_Chain) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorConfig_Chain.ProtoReflect.Descriptor instead.
+func (*ChainGovernorConfig_Chain) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{10, 0}
+}
+
+func (x *ChainGovernorConfig_Chain) GetChainId() uint32 {
+	if x != nil {
+		return x.ChainId
+	}
+	return 0
+}
+
+func (x *ChainGovernorConfig_Chain) GetNotionalLimit() uint64 {
+	if x != nil {
+		return x.NotionalLimit
+	}
+	return 0
+}
+
+func (x *ChainGovernorConfig_Chain) GetBigTransactionSize() uint64 {
+	if x != nil {
+		return x.BigTransactionSize
+	}
+	return 0
+}
+
+type ChainGovernorConfig_Token struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	OriginChainId uint32  `protobuf:"varint,1,opt,name=origin_chain_id,json=originChainId,proto3" json:"origin_chain_id,omitempty"`
+	OriginAddress string  `protobuf:"bytes,2,opt,name=origin_address,json=originAddress,proto3" json:"origin_address,omitempty"` // human-readable hex-encoded (leading 0x)
+	Price         float32 `protobuf:"fixed32,3,opt,name=price,proto3" json:"price,omitempty"`
+}
+
+func (x *ChainGovernorConfig_Token) Reset() {
+	*x = ChainGovernorConfig_Token{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorConfig_Token) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorConfig_Token) ProtoMessage() {}
+
+func (x *ChainGovernorConfig_Token) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorConfig_Token.ProtoReflect.Descriptor instead.
+func (*ChainGovernorConfig_Token) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{10, 1}
+}
+
+func (x *ChainGovernorConfig_Token) GetOriginChainId() uint32 {
+	if x != nil {
+		return x.OriginChainId
+	}
+	return 0
+}
+
+func (x *ChainGovernorConfig_Token) GetOriginAddress() string {
+	if x != nil {
+		return x.OriginAddress
+	}
+	return ""
+}
+
+func (x *ChainGovernorConfig_Token) GetPrice() float32 {
+	if x != nil {
+		return x.Price
+	}
+	return 0
+}
+
+type ChainGovernorStatus_EnqueuedVAA struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Sequence      uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` // Chain and emitter address are assumed.
+	ReleaseTime   uint32 `protobuf:"varint,2,opt,name=release_time,json=releaseTime,proto3" json:"release_time,omitempty"`
+	NotionalValue uint64 `protobuf:"varint,3,opt,name=notional_value,json=notionalValue,proto3" json:"notional_value,omitempty"`
+	TxHash        string `protobuf:"bytes,4,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"`
+}
+
+func (x *ChainGovernorStatus_EnqueuedVAA) Reset() {
+	*x = ChainGovernorStatus_EnqueuedVAA{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[16]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorStatus_EnqueuedVAA) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorStatus_EnqueuedVAA) ProtoMessage() {}
+
+func (x *ChainGovernorStatus_EnqueuedVAA) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[16]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorStatus_EnqueuedVAA.ProtoReflect.Descriptor instead.
+func (*ChainGovernorStatus_EnqueuedVAA) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{12, 0}
+}
+
+func (x *ChainGovernorStatus_EnqueuedVAA) GetSequence() uint64 {
+	if x != nil {
+		return x.Sequence
+	}
+	return 0
+}
+
+func (x *ChainGovernorStatus_EnqueuedVAA) GetReleaseTime() uint32 {
+	if x != nil {
+		return x.ReleaseTime
+	}
+	return 0
+}
+
+func (x *ChainGovernorStatus_EnqueuedVAA) GetNotionalValue() uint64 {
+	if x != nil {
+		return x.NotionalValue
+	}
+	return 0
+}
+
+func (x *ChainGovernorStatus_EnqueuedVAA) GetTxHash() string {
+	if x != nil {
+		return x.TxHash
+	}
+	return ""
+}
+
+type ChainGovernorStatus_Emitter struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	EmitterAddress    string                             `protobuf:"bytes,1,opt,name=emitter_address,json=emitterAddress,proto3" json:"emitter_address,omitempty"` // human-readable hex-encoded (leading 0x)
+	TotalEnqueuedVaas uint64                             `protobuf:"varint,2,opt,name=total_enqueued_vaas,json=totalEnqueuedVaas,proto3" json:"total_enqueued_vaas,omitempty"`
+	EnqueuedVaas      []*ChainGovernorStatus_EnqueuedVAA `protobuf:"bytes,3,rep,name=enqueued_vaas,json=enqueuedVaas,proto3" json:"enqueued_vaas,omitempty"` // Only the first 20 will be included.
+}
+
+func (x *ChainGovernorStatus_Emitter) Reset() {
+	*x = ChainGovernorStatus_Emitter{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[17]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorStatus_Emitter) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorStatus_Emitter) ProtoMessage() {}
+
+func (x *ChainGovernorStatus_Emitter) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[17]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorStatus_Emitter.ProtoReflect.Descriptor instead.
+func (*ChainGovernorStatus_Emitter) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{12, 1}
+}
+
+func (x *ChainGovernorStatus_Emitter) GetEmitterAddress() string {
+	if x != nil {
+		return x.EmitterAddress
+	}
+	return ""
+}
+
+func (x *ChainGovernorStatus_Emitter) GetTotalEnqueuedVaas() uint64 {
+	if x != nil {
+		return x.TotalEnqueuedVaas
+	}
+	return 0
+}
+
+func (x *ChainGovernorStatus_Emitter) GetEnqueuedVaas() []*ChainGovernorStatus_EnqueuedVAA {
+	if x != nil {
+		return x.EnqueuedVaas
+	}
+	return nil
+}
+
+type ChainGovernorStatus_Chain struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ChainId                    uint32                         `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
+	RemainingAvailableNotional uint64                         `protobuf:"varint,2,opt,name=remaining_available_notional,json=remainingAvailableNotional,proto3" json:"remaining_available_notional,omitempty"`
+	Emitters                   []*ChainGovernorStatus_Emitter `protobuf:"bytes,3,rep,name=emitters,proto3" json:"emitters,omitempty"`
+}
+
+func (x *ChainGovernorStatus_Chain) Reset() {
+	*x = ChainGovernorStatus_Chain{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gossip_v1_gossip_proto_msgTypes[18]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorStatus_Chain) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorStatus_Chain) ProtoMessage() {}
+
+func (x *ChainGovernorStatus_Chain) ProtoReflect() protoreflect.Message {
+	mi := &file_gossip_v1_gossip_proto_msgTypes[18]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorStatus_Chain.ProtoReflect.Descriptor instead.
+func (*ChainGovernorStatus_Chain) Descriptor() ([]byte, []int) {
+	return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{12, 2}
+}
+
+func (x *ChainGovernorStatus_Chain) GetChainId() uint32 {
+	if x != nil {
+		return x.ChainId
+	}
+	return 0
+}
+
+func (x *ChainGovernorStatus_Chain) GetRemainingAvailableNotional() uint64 {
+	if x != nil {
+		return x.RemainingAvailableNotional
+	}
+	return 0
+}
+
+func (x *ChainGovernorStatus_Chain) GetEmitters() []*ChainGovernorStatus_Emitter {
+	if x != nil {
+		return x.Emitters
+	}
+	return nil
+}
+
+var File_gossip_v1_gossip_proto protoreflect.FileDescriptor
+
+var file_gossip_v1_gossip_proto_rawDesc = []byte{
+	0x0a, 0x16, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x73, 0x73,
+	0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70,
+	0x2e, 0x76, 0x31, 0x22, 0x86, 0x06, 0x0a, 0x0d, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x4d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x4d, 0x0a, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f,
+	0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69,
+	0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48,
+	0x00, 0x52, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x68,
+	0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
+	0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65,
+	0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x69,
+	0x67, 0x6e, 0x65, 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x55, 0x0a,
+	0x16, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x61, 0x5f, 0x77, 0x69, 0x74, 0x68,
+	0x5f, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e,
+	0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64,
+	0x56, 0x41, 0x41, 0x57, 0x69, 0x74, 0x68, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x48, 0x00, 0x52,
+	0x13, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x61, 0x61, 0x57, 0x69, 0x74, 0x68, 0x51, 0x75,
+	0x6f, 0x72, 0x75, 0x6d, 0x12, 0x63, 0x0a, 0x1a, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6f,
+	0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69,
+	0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72,
+	0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52,
+	0x18, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5d, 0x0a, 0x18, 0x73, 0x69, 0x67,
+	0x6e, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f,
+	0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x61,
+	0x74, 0x63, 0x68, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00,
+	0x52, 0x16, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x62, 0x73,
+	0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x65, 0x0a, 0x1c, 0x73, 0x69, 0x67, 0x6e,
+	0x65, 0x64, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x76, 0x61, 0x61, 0x5f, 0x77, 0x69, 0x74,
+	0x68, 0x5f, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23,
+	0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65,
+	0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x56, 0x41, 0x41, 0x57, 0x69, 0x74, 0x68, 0x51, 0x75, 0x6f,
+	0x72, 0x75, 0x6d, 0x48, 0x00, 0x52, 0x18, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x74,
+	0x63, 0x68, 0x56, 0x61, 0x61, 0x57, 0x69, 0x74, 0x68, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x12,
+	0x67, 0x0a, 0x1c, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f,
+	0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18,
+	0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76,
+	0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76,
+	0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x19, 0x73,
+	0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e,
+	0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x67, 0x0a, 0x1c, 0x73, 0x69, 0x67, 0x6e,
+	0x65, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f,
+	0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24,
+	0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65,
+	0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x19, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68,
+	0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x72, 0x0a, 0x0f,
+	0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12,
+	0x1c, 0x0a, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x1c, 0x0a,
+	0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
+	0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67,
+	0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x0c, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72,
+	0x22, 0x9b, 0x03, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x1b,
+	0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63,
+	0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x6f,
+	0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+	0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x12, 0x38, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x18,
+	0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76,
+	0x31, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77,
+	0x6f, 0x72, 0x6b, 0x52, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x18, 0x0a,
+	0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+	0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x75, 0x61, 0x72, 0x64,
+	0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
+	0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x12, 0x25, 0x0a, 0x0e,
+	0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x62, 0x6f, 0x6f, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18,
+	0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x1a,
+	0x7d, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65,
+	0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67,
+	0x68, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x61,
+	0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6f,
+	0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x0a,
+	0x0b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x04, 0x52, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x91,
+	0x01, 0x0a, 0x11, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09,
+	0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52,
+	0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78,
+	0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48,
+	0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69,
+	0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x49, 0x64, 0x22, 0x27, 0x0a, 0x13, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x57,
+	0x69, 0x74, 0x68, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x61,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x76, 0x61, 0x61, 0x22, 0x8e, 0x01, 0x0a, 0x18,
+	0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x13, 0x6f, 0x62, 0x73, 0x65,
+	0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67,
+	0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69,
+	0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x75, 0x61, 0x72, 0x64,
+	0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c,
+	0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x22, 0x48, 0x0a, 0x12,
+	0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a,
+	0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06,
+	0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0xad, 0x01, 0x0a, 0x16, 0x53, 0x69, 0x67, 0x6e, 0x65,
+	0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
+	0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67,
+	0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69,
+	0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61,
+	0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68,
+	0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01,
+	0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62,
+	0x61, 0x74, 0x63, 0x68, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62,
+	0x61, 0x74, 0x63, 0x68, 0x49, 0x64, 0x22, 0x37, 0x0a, 0x18, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64,
+	0x42, 0x61, 0x74, 0x63, 0x68, 0x56, 0x41, 0x41, 0x57, 0x69, 0x74, 0x68, 0x51, 0x75, 0x6f, 0x72,
+	0x75, 0x6d, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x76, 0x61, 0x61, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x62, 0x61, 0x74, 0x63, 0x68, 0x56, 0x61, 0x61, 0x22,
+	0x76, 0x0a, 0x19, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f,
+	0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x0a, 0x06,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
+	0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x61,
+	0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x67, 0x75, 0x61, 0x72, 0x64,
+	0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x22, 0xd1, 0x03, 0x0a, 0x13, 0x43, 0x68, 0x61, 0x69,
+	0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+	0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63,
+	0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
+	0x74, 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x04,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31,
+	0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x63, 0x68, 0x61, 0x69,
+	0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43,
+	0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73,
+	0x1a, 0x7b, 0x0a, 0x05, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61,
+	0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61,
+	0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
+	0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6e, 0x6f,
+	0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x62,
+	0x69, 0x67, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73,
+	0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x62, 0x69, 0x67, 0x54, 0x72,
+	0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x1a, 0x6c, 0x0a,
+	0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e,
+	0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
+	0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x25,
+	0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x41, 0x64,
+	0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x22, 0x76, 0x0a, 0x19, 0x53,
+	0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e,
+	0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74,
+	0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23,
+	0x0a, 0x0d, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41,
+	0x64, 0x64, 0x72, 0x22, 0x98, 0x05, 0x0a, 0x13, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76,
+	0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6e,
+	0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
+	0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e,
+	0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+	0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
+	0x12, 0x3c, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61,
+	0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x1a, 0x8c,
+	0x01, 0x0a, 0x0b, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, 0x12, 0x1a,
+	0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
+	0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65,
+	0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d,
+	0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x25, 0x0a,
+	0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x56,
+	0x61, 0x6c, 0x75, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18,
+	0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x1a, 0xb3, 0x01,
+	0x0a, 0x07, 0x45, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6d, 0x69,
+	0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65,
+	0x73, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x71, 0x75,
+	0x65, 0x75, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
+	0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x61,
+	0x61, 0x73, 0x12, 0x4f, 0x0a, 0x0d, 0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x5f, 0x76,
+	0x61, 0x61, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x73, 0x73,
+	0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72,
+	0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75,
+	0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x0c, 0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56,
+	0x61, 0x61, 0x73, 0x1a, 0xa8, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x19, 0x0a,
+	0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
+	0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x1c, 0x72, 0x65, 0x6d, 0x61,
+	0x69, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f,
+	0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a,
+	0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62,
+	0x6c, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x42, 0x0a, 0x08, 0x65, 0x6d,
+	0x69, 0x74, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67,
+	0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f,
+	0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x45, 0x6d, 0x69,
+	0x74, 0x74, 0x65, 0x72, 0x52, 0x08, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x73, 0x42, 0x41,
+	0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72,
+	0x74, 0x75, 0x73, 0x6f, 0x6e, 0x65, 0x2f, 0x77, 0x6f, 0x72, 0x6d, 0x68, 0x6f, 0x6c, 0x65, 0x2f,
+	0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67,
+	0x6f, 0x73, 0x73, 0x69, 0x70, 0x2f, 0x76, 0x31, 0x3b, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x76,
+	0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_gossip_v1_gossip_proto_rawDescOnce sync.Once
+	file_gossip_v1_gossip_proto_rawDescData = file_gossip_v1_gossip_proto_rawDesc
+)
+
+func file_gossip_v1_gossip_proto_rawDescGZIP() []byte {
+	file_gossip_v1_gossip_proto_rawDescOnce.Do(func() {
+		file_gossip_v1_gossip_proto_rawDescData = protoimpl.X.CompressGZIP(file_gossip_v1_gossip_proto_rawDescData)
+	})
+	return file_gossip_v1_gossip_proto_rawDescData
+}
+
+var file_gossip_v1_gossip_proto_msgTypes = make([]protoimpl.MessageInfo, 19)
+var file_gossip_v1_gossip_proto_goTypes = []interface{}{
+	(*GossipMessage)(nil),                   // 0: gossip.v1.GossipMessage
+	(*SignedHeartbeat)(nil),                 // 1: gossip.v1.SignedHeartbeat
+	(*Heartbeat)(nil),                       // 2: gossip.v1.Heartbeat
+	(*SignedObservation)(nil),               // 3: gossip.v1.SignedObservation
+	(*SignedVAAWithQuorum)(nil),             // 4: gossip.v1.SignedVAAWithQuorum
+	(*SignedObservationRequest)(nil),        // 5: gossip.v1.SignedObservationRequest
+	(*ObservationRequest)(nil),              // 6: gossip.v1.ObservationRequest
+	(*SignedBatchObservation)(nil),          // 7: gossip.v1.SignedBatchObservation
+	(*SignedBatchVAAWithQuorum)(nil),        // 8: gossip.v1.SignedBatchVAAWithQuorum
+	(*SignedChainGovernorConfig)(nil),       // 9: gossip.v1.SignedChainGovernorConfig
+	(*ChainGovernorConfig)(nil),             // 10: gossip.v1.ChainGovernorConfig
+	(*SignedChainGovernorStatus)(nil),       // 11: gossip.v1.SignedChainGovernorStatus
+	(*ChainGovernorStatus)(nil),             // 12: gossip.v1.ChainGovernorStatus
+	(*Heartbeat_Network)(nil),               // 13: gossip.v1.Heartbeat.Network
+	(*ChainGovernorConfig_Chain)(nil),       // 14: gossip.v1.ChainGovernorConfig.Chain
+	(*ChainGovernorConfig_Token)(nil),       // 15: gossip.v1.ChainGovernorConfig.Token
+	(*ChainGovernorStatus_EnqueuedVAA)(nil), // 16: gossip.v1.ChainGovernorStatus.EnqueuedVAA
+	(*ChainGovernorStatus_Emitter)(nil),     // 17: gossip.v1.ChainGovernorStatus.Emitter
+	(*ChainGovernorStatus_Chain)(nil),       // 18: gossip.v1.ChainGovernorStatus.Chain
+}
+var file_gossip_v1_gossip_proto_depIdxs = []int32{
+	3,  // 0: gossip.v1.GossipMessage.signed_observation:type_name -> gossip.v1.SignedObservation
+	1,  // 1: gossip.v1.GossipMessage.signed_heartbeat:type_name -> gossip.v1.SignedHeartbeat
+	4,  // 2: gossip.v1.GossipMessage.signed_vaa_with_quorum:type_name -> gossip.v1.SignedVAAWithQuorum
+	5,  // 3: gossip.v1.GossipMessage.signed_observation_request:type_name -> gossip.v1.SignedObservationRequest
+	7,  // 4: gossip.v1.GossipMessage.signed_batch_observation:type_name -> gossip.v1.SignedBatchObservation
+	8,  // 5: gossip.v1.GossipMessage.signed_batch_vaa_with_quorum:type_name -> gossip.v1.SignedBatchVAAWithQuorum
+	9,  // 6: gossip.v1.GossipMessage.signed_chain_governor_config:type_name -> gossip.v1.SignedChainGovernorConfig
+	11, // 7: gossip.v1.GossipMessage.signed_chain_governor_status:type_name -> gossip.v1.SignedChainGovernorStatus
+	13, // 8: gossip.v1.Heartbeat.networks:type_name -> gossip.v1.Heartbeat.Network
+	14, // 9: gossip.v1.ChainGovernorConfig.chains:type_name -> gossip.v1.ChainGovernorConfig.Chain
+	15, // 10: gossip.v1.ChainGovernorConfig.tokens:type_name -> gossip.v1.ChainGovernorConfig.Token
+	18, // 11: gossip.v1.ChainGovernorStatus.chains:type_name -> gossip.v1.ChainGovernorStatus.Chain
+	16, // 12: gossip.v1.ChainGovernorStatus.Emitter.enqueued_vaas:type_name -> gossip.v1.ChainGovernorStatus.EnqueuedVAA
+	17, // 13: gossip.v1.ChainGovernorStatus.Chain.emitters:type_name -> gossip.v1.ChainGovernorStatus.Emitter
+	14, // [14:14] is the sub-list for method output_type
+	14, // [14:14] is the sub-list for method input_type
+	14, // [14:14] is the sub-list for extension type_name
+	14, // [14:14] is the sub-list for extension extendee
+	0,  // [0:14] is the sub-list for field type_name
+}
+
+func init() { file_gossip_v1_gossip_proto_init() }
+func file_gossip_v1_gossip_proto_init() {
+	if File_gossip_v1_gossip_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_gossip_v1_gossip_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GossipMessage); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SignedHeartbeat); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Heartbeat); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SignedObservation); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SignedVAAWithQuorum); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SignedObservationRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ObservationRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SignedBatchObservation); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SignedBatchVAAWithQuorum); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SignedChainGovernorConfig); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorConfig); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SignedChainGovernorStatus); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorStatus); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Heartbeat_Network); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorConfig_Chain); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorConfig_Token); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorStatus_EnqueuedVAA); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorStatus_Emitter); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gossip_v1_gossip_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorStatus_Chain); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_gossip_v1_gossip_proto_msgTypes[0].OneofWrappers = []interface{}{
+		(*GossipMessage_SignedObservation)(nil),
+		(*GossipMessage_SignedHeartbeat)(nil),
+		(*GossipMessage_SignedVaaWithQuorum)(nil),
+		(*GossipMessage_SignedObservationRequest)(nil),
+		(*GossipMessage_SignedBatchObservation)(nil),
+		(*GossipMessage_SignedBatchVaaWithQuorum)(nil),
+		(*GossipMessage_SignedChainGovernorConfig)(nil),
+		(*GossipMessage_SignedChainGovernorStatus)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_gossip_v1_gossip_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   19,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_gossip_v1_gossip_proto_goTypes,
+		DependencyIndexes: file_gossip_v1_gossip_proto_depIdxs,
+		MessageInfos:      file_gossip_v1_gossip_proto_msgTypes,
+	}.Build()
+	File_gossip_v1_gossip_proto = out.File
+	file_gossip_v1_gossip_proto_rawDesc = nil
+	file_gossip_v1_gossip_proto_goTypes = nil
+	file_gossip_v1_gossip_proto_depIdxs = nil
+}

+ 2032 - 0
node/pkg/proto/node/v1/node.pb.go

@@ -0,0 +1,2032 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.27.1
+// 	protoc        (unknown)
+// source: node/v1/node.proto
+
+package nodev1
+
+import (
+	v1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type InjectGovernanceVAARequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Index of the current guardian set.
+	CurrentSetIndex uint32 `protobuf:"varint,1,opt,name=current_set_index,json=currentSetIndex,proto3" json:"current_set_index,omitempty"`
+	// List of governance VAA messages to inject.
+	Messages []*GovernanceMessage `protobuf:"bytes,2,rep,name=messages,proto3" json:"messages,omitempty"`
+	// UNIX wall time in seconds
+	Timestamp uint32 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+}
+
+func (x *InjectGovernanceVAARequest) Reset() {
+	*x = InjectGovernanceVAARequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InjectGovernanceVAARequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InjectGovernanceVAARequest) ProtoMessage() {}
+
+func (x *InjectGovernanceVAARequest) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InjectGovernanceVAARequest.ProtoReflect.Descriptor instead.
+func (*InjectGovernanceVAARequest) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *InjectGovernanceVAARequest) GetCurrentSetIndex() uint32 {
+	if x != nil {
+		return x.CurrentSetIndex
+	}
+	return 0
+}
+
+func (x *InjectGovernanceVAARequest) GetMessages() []*GovernanceMessage {
+	if x != nil {
+		return x.Messages
+	}
+	return nil
+}
+
+func (x *InjectGovernanceVAARequest) GetTimestamp() uint32 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+type GovernanceMessage struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Sequence number. This is critical for replay protection - make sure the sequence number
+	// is unique for every new manually injected governance VAA. Sequences are tracked
+	// by emitter, and manually injected VAAs all use a single hardcoded emitter.
+	//
+	// We use random sequence numbers for the manual emitter.
+	Sequence uint64 `protobuf:"varint,2,opt,name=sequence,proto3" json:"sequence,omitempty"`
+	// Random nonce for disambiguation. Must be identical across all nodes.
+	Nonce uint32 `protobuf:"varint,3,opt,name=nonce,proto3" json:"nonce,omitempty"`
+	// Types that are assignable to Payload:
+	//	*GovernanceMessage_GuardianSet
+	//	*GovernanceMessage_ContractUpgrade
+	//	*GovernanceMessage_BridgeRegisterChain
+	//	*GovernanceMessage_BridgeContractUpgrade
+	Payload isGovernanceMessage_Payload `protobuf_oneof:"payload"`
+}
+
+func (x *GovernanceMessage) Reset() {
+	*x = GovernanceMessage{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernanceMessage) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernanceMessage) ProtoMessage() {}
+
+func (x *GovernanceMessage) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernanceMessage.ProtoReflect.Descriptor instead.
+func (*GovernanceMessage) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *GovernanceMessage) GetSequence() uint64 {
+	if x != nil {
+		return x.Sequence
+	}
+	return 0
+}
+
+func (x *GovernanceMessage) GetNonce() uint32 {
+	if x != nil {
+		return x.Nonce
+	}
+	return 0
+}
+
+func (m *GovernanceMessage) GetPayload() isGovernanceMessage_Payload {
+	if m != nil {
+		return m.Payload
+	}
+	return nil
+}
+
+func (x *GovernanceMessage) GetGuardianSet() *GuardianSetUpdate {
+	if x, ok := x.GetPayload().(*GovernanceMessage_GuardianSet); ok {
+		return x.GuardianSet
+	}
+	return nil
+}
+
+func (x *GovernanceMessage) GetContractUpgrade() *ContractUpgrade {
+	if x, ok := x.GetPayload().(*GovernanceMessage_ContractUpgrade); ok {
+		return x.ContractUpgrade
+	}
+	return nil
+}
+
+func (x *GovernanceMessage) GetBridgeRegisterChain() *BridgeRegisterChain {
+	if x, ok := x.GetPayload().(*GovernanceMessage_BridgeRegisterChain); ok {
+		return x.BridgeRegisterChain
+	}
+	return nil
+}
+
+func (x *GovernanceMessage) GetBridgeContractUpgrade() *BridgeUpgradeContract {
+	if x, ok := x.GetPayload().(*GovernanceMessage_BridgeContractUpgrade); ok {
+		return x.BridgeContractUpgrade
+	}
+	return nil
+}
+
+type isGovernanceMessage_Payload interface {
+	isGovernanceMessage_Payload()
+}
+
+type GovernanceMessage_GuardianSet struct {
+	GuardianSet *GuardianSetUpdate `protobuf:"bytes,10,opt,name=guardian_set,json=guardianSet,proto3,oneof"`
+}
+
+type GovernanceMessage_ContractUpgrade struct {
+	ContractUpgrade *ContractUpgrade `protobuf:"bytes,11,opt,name=contract_upgrade,json=contractUpgrade,proto3,oneof"`
+}
+
+type GovernanceMessage_BridgeRegisterChain struct {
+	BridgeRegisterChain *BridgeRegisterChain `protobuf:"bytes,12,opt,name=bridge_register_chain,json=bridgeRegisterChain,proto3,oneof"`
+}
+
+type GovernanceMessage_BridgeContractUpgrade struct {
+	BridgeContractUpgrade *BridgeUpgradeContract `protobuf:"bytes,13,opt,name=bridge_contract_upgrade,json=bridgeContractUpgrade,proto3,oneof"`
+}
+
+func (*GovernanceMessage_GuardianSet) isGovernanceMessage_Payload() {}
+
+func (*GovernanceMessage_ContractUpgrade) isGovernanceMessage_Payload() {}
+
+func (*GovernanceMessage_BridgeRegisterChain) isGovernanceMessage_Payload() {}
+
+func (*GovernanceMessage_BridgeContractUpgrade) isGovernanceMessage_Payload() {}
+
+type InjectGovernanceVAAResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Canonical digests of the submitted VAAs.
+	Digests [][]byte `protobuf:"bytes,1,rep,name=digests,proto3" json:"digests,omitempty"`
+}
+
+func (x *InjectGovernanceVAAResponse) Reset() {
+	*x = InjectGovernanceVAAResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InjectGovernanceVAAResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InjectGovernanceVAAResponse) ProtoMessage() {}
+
+func (x *InjectGovernanceVAAResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InjectGovernanceVAAResponse.ProtoReflect.Descriptor instead.
+func (*InjectGovernanceVAAResponse) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *InjectGovernanceVAAResponse) GetDigests() [][]byte {
+	if x != nil {
+		return x.Digests
+	}
+	return nil
+}
+
+// GuardianSet represents a new guardian set to be submitted to and signed by the node.
+// During the genesis procedure, this data structure will be assembled using off-chain collaborative tooling
+// like GitHub using a human-readable encoding, so readability is a concern.
+type GuardianSetUpdate struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Guardians []*GuardianSetUpdate_Guardian `protobuf:"bytes,3,rep,name=guardians,proto3" json:"guardians,omitempty"`
+}
+
+func (x *GuardianSetUpdate) Reset() {
+	*x = GuardianSetUpdate{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GuardianSetUpdate) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GuardianSetUpdate) ProtoMessage() {}
+
+func (x *GuardianSetUpdate) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GuardianSetUpdate.ProtoReflect.Descriptor instead.
+func (*GuardianSetUpdate) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *GuardianSetUpdate) GetGuardians() []*GuardianSetUpdate_Guardian {
+	if x != nil {
+		return x.Guardians
+	}
+	return nil
+}
+
+// GuardianKey specifies the on-disk format for a node's guardian key.
+type GuardianKey struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// data is the binary representation of the secp256k1 private key.
+	Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
+	// Whether this key is deterministically generated and unsuitable for production mode.
+	UnsafeDeterministicKey bool `protobuf:"varint,2,opt,name=unsafe_deterministic_key,json=unsafeDeterministicKey,proto3" json:"unsafe_deterministic_key,omitempty"`
+}
+
+func (x *GuardianKey) Reset() {
+	*x = GuardianKey{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GuardianKey) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GuardianKey) ProtoMessage() {}
+
+func (x *GuardianKey) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GuardianKey.ProtoReflect.Descriptor instead.
+func (*GuardianKey) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *GuardianKey) GetData() []byte {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+func (x *GuardianKey) GetUnsafeDeterministicKey() bool {
+	if x != nil {
+		return x.UnsafeDeterministicKey
+	}
+	return false
+}
+
+type BridgeRegisterChain struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Module identifier of the token or NFT bridge (typically "TokenBridge" or "NFTBridge")
+	Module string `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"`
+	// ID of the chain to be registered.
+	ChainId uint32 `protobuf:"varint,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
+	// Hex-encoded emitter address to be registered (without leading 0x).
+	EmitterAddress string `protobuf:"bytes,3,opt,name=emitter_address,json=emitterAddress,proto3" json:"emitter_address,omitempty"`
+}
+
+func (x *BridgeRegisterChain) Reset() {
+	*x = BridgeRegisterChain{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *BridgeRegisterChain) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BridgeRegisterChain) ProtoMessage() {}
+
+func (x *BridgeRegisterChain) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use BridgeRegisterChain.ProtoReflect.Descriptor instead.
+func (*BridgeRegisterChain) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *BridgeRegisterChain) GetModule() string {
+	if x != nil {
+		return x.Module
+	}
+	return ""
+}
+
+func (x *BridgeRegisterChain) GetChainId() uint32 {
+	if x != nil {
+		return x.ChainId
+	}
+	return 0
+}
+
+func (x *BridgeRegisterChain) GetEmitterAddress() string {
+	if x != nil {
+		return x.EmitterAddress
+	}
+	return ""
+}
+
+// ContractUpgrade represents a Wormhole contract update to be submitted to and signed by the node.
+type ContractUpgrade struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// ID of the chain where the Wormhole contract should be updated (uint8).
+	ChainId uint32 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
+	// Hex-encoded address (without leading 0x) address of the new program/contract.
+	NewContract string `protobuf:"bytes,2,opt,name=new_contract,json=newContract,proto3" json:"new_contract,omitempty"`
+}
+
+func (x *ContractUpgrade) Reset() {
+	*x = ContractUpgrade{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ContractUpgrade) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ContractUpgrade) ProtoMessage() {}
+
+func (x *ContractUpgrade) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ContractUpgrade.ProtoReflect.Descriptor instead.
+func (*ContractUpgrade) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *ContractUpgrade) GetChainId() uint32 {
+	if x != nil {
+		return x.ChainId
+	}
+	return 0
+}
+
+func (x *ContractUpgrade) GetNewContract() string {
+	if x != nil {
+		return x.NewContract
+	}
+	return ""
+}
+
+type BridgeUpgradeContract struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Module identifier of the token or NFT bridge (typically "TokenBridge" or "NFTBridge").
+	Module string `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"`
+	// ID of the chain where the bridge contract should be updated (uint16).
+	TargetChainId uint32 `protobuf:"varint,2,opt,name=target_chain_id,json=targetChainId,proto3" json:"target_chain_id,omitempty"`
+	// Hex-encoded address (without leading 0x) of the new program/contract.
+	NewContract string `protobuf:"bytes,3,opt,name=new_contract,json=newContract,proto3" json:"new_contract,omitempty"`
+}
+
+func (x *BridgeUpgradeContract) Reset() {
+	*x = BridgeUpgradeContract{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *BridgeUpgradeContract) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BridgeUpgradeContract) ProtoMessage() {}
+
+func (x *BridgeUpgradeContract) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use BridgeUpgradeContract.ProtoReflect.Descriptor instead.
+func (*BridgeUpgradeContract) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *BridgeUpgradeContract) GetModule() string {
+	if x != nil {
+		return x.Module
+	}
+	return ""
+}
+
+func (x *BridgeUpgradeContract) GetTargetChainId() uint32 {
+	if x != nil {
+		return x.TargetChainId
+	}
+	return 0
+}
+
+func (x *BridgeUpgradeContract) GetNewContract() string {
+	if x != nil {
+		return x.NewContract
+	}
+	return ""
+}
+
+type FindMissingMessagesRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Emitter chain ID to iterate.
+	EmitterChain uint32 `protobuf:"varint,1,opt,name=emitter_chain,json=emitterChain,proto3" json:"emitter_chain,omitempty"`
+	// Hex-encoded (without leading 0x) emitter address to iterate.
+	EmitterAddress string `protobuf:"bytes,2,opt,name=emitter_address,json=emitterAddress,proto3" json:"emitter_address,omitempty"`
+	// Whether to attempt to backfill missing messages from a list of remote nodes.
+	RpcBackfill bool `protobuf:"varint,3,opt,name=rpc_backfill,json=rpcBackfill,proto3" json:"rpc_backfill,omitempty"`
+	// List of remote nodes to backfill from.
+	BackfillNodes []string `protobuf:"bytes,4,rep,name=backfill_nodes,json=backfillNodes,proto3" json:"backfill_nodes,omitempty"`
+}
+
+func (x *FindMissingMessagesRequest) Reset() {
+	*x = FindMissingMessagesRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FindMissingMessagesRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FindMissingMessagesRequest) ProtoMessage() {}
+
+func (x *FindMissingMessagesRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FindMissingMessagesRequest.ProtoReflect.Descriptor instead.
+func (*FindMissingMessagesRequest) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *FindMissingMessagesRequest) GetEmitterChain() uint32 {
+	if x != nil {
+		return x.EmitterChain
+	}
+	return 0
+}
+
+func (x *FindMissingMessagesRequest) GetEmitterAddress() string {
+	if x != nil {
+		return x.EmitterAddress
+	}
+	return ""
+}
+
+func (x *FindMissingMessagesRequest) GetRpcBackfill() bool {
+	if x != nil {
+		return x.RpcBackfill
+	}
+	return false
+}
+
+func (x *FindMissingMessagesRequest) GetBackfillNodes() []string {
+	if x != nil {
+		return x.BackfillNodes
+	}
+	return nil
+}
+
+type FindMissingMessagesResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// List of missing sequence numbers.
+	MissingMessages []string `protobuf:"bytes,1,rep,name=missing_messages,json=missingMessages,proto3" json:"missing_messages,omitempty"`
+	// Range processed
+	FirstSequence uint64 `protobuf:"varint,2,opt,name=first_sequence,json=firstSequence,proto3" json:"first_sequence,omitempty"`
+	LastSequence  uint64 `protobuf:"varint,3,opt,name=last_sequence,json=lastSequence,proto3" json:"last_sequence,omitempty"`
+}
+
+func (x *FindMissingMessagesResponse) Reset() {
+	*x = FindMissingMessagesResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FindMissingMessagesResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FindMissingMessagesResponse) ProtoMessage() {}
+
+func (x *FindMissingMessagesResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FindMissingMessagesResponse.ProtoReflect.Descriptor instead.
+func (*FindMissingMessagesResponse) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *FindMissingMessagesResponse) GetMissingMessages() []string {
+	if x != nil {
+		return x.MissingMessages
+	}
+	return nil
+}
+
+func (x *FindMissingMessagesResponse) GetFirstSequence() uint64 {
+	if x != nil {
+		return x.FirstSequence
+	}
+	return 0
+}
+
+func (x *FindMissingMessagesResponse) GetLastSequence() uint64 {
+	if x != nil {
+		return x.LastSequence
+	}
+	return 0
+}
+
+type SendObservationRequestRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ObservationRequest *v1.ObservationRequest `protobuf:"bytes,1,opt,name=observation_request,json=observationRequest,proto3" json:"observation_request,omitempty"`
+}
+
+func (x *SendObservationRequestRequest) Reset() {
+	*x = SendObservationRequestRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[10]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SendObservationRequestRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendObservationRequestRequest) ProtoMessage() {}
+
+func (x *SendObservationRequestRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[10]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SendObservationRequestRequest.ProtoReflect.Descriptor instead.
+func (*SendObservationRequestRequest) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *SendObservationRequestRequest) GetObservationRequest() *v1.ObservationRequest {
+	if x != nil {
+		return x.ObservationRequest
+	}
+	return nil
+}
+
+type SendObservationRequestResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *SendObservationRequestResponse) Reset() {
+	*x = SendObservationRequestResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SendObservationRequestResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendObservationRequestResponse) ProtoMessage() {}
+
+func (x *SendObservationRequestResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SendObservationRequestResponse.ProtoReflect.Descriptor instead.
+func (*SendObservationRequestResponse) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{11}
+}
+
+type ChainGovernorStatusRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *ChainGovernorStatusRequest) Reset() {
+	*x = ChainGovernorStatusRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorStatusRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorStatusRequest) ProtoMessage() {}
+
+func (x *ChainGovernorStatusRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorStatusRequest.ProtoReflect.Descriptor instead.
+func (*ChainGovernorStatusRequest) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{12}
+}
+
+type ChainGovernorStatusResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Response string `protobuf:"bytes,1,opt,name=response,proto3" json:"response,omitempty"`
+}
+
+func (x *ChainGovernorStatusResponse) Reset() {
+	*x = ChainGovernorStatusResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorStatusResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorStatusResponse) ProtoMessage() {}
+
+func (x *ChainGovernorStatusResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorStatusResponse.ProtoReflect.Descriptor instead.
+func (*ChainGovernorStatusResponse) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *ChainGovernorStatusResponse) GetResponse() string {
+	if x != nil {
+		return x.Response
+	}
+	return ""
+}
+
+type ChainGovernorReloadRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *ChainGovernorReloadRequest) Reset() {
+	*x = ChainGovernorReloadRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorReloadRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorReloadRequest) ProtoMessage() {}
+
+func (x *ChainGovernorReloadRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorReloadRequest.ProtoReflect.Descriptor instead.
+func (*ChainGovernorReloadRequest) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{14}
+}
+
+type ChainGovernorReloadResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Response string `protobuf:"bytes,1,opt,name=response,proto3" json:"response,omitempty"`
+}
+
+func (x *ChainGovernorReloadResponse) Reset() {
+	*x = ChainGovernorReloadResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorReloadResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorReloadResponse) ProtoMessage() {}
+
+func (x *ChainGovernorReloadResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorReloadResponse.ProtoReflect.Descriptor instead.
+func (*ChainGovernorReloadResponse) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{15}
+}
+
+func (x *ChainGovernorReloadResponse) GetResponse() string {
+	if x != nil {
+		return x.Response
+	}
+	return ""
+}
+
+type ChainGovernorDropPendingVAARequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	VaaId string `protobuf:"bytes,1,opt,name=vaa_id,json=vaaId,proto3" json:"vaa_id,omitempty"`
+}
+
+func (x *ChainGovernorDropPendingVAARequest) Reset() {
+	*x = ChainGovernorDropPendingVAARequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[16]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorDropPendingVAARequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorDropPendingVAARequest) ProtoMessage() {}
+
+func (x *ChainGovernorDropPendingVAARequest) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[16]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorDropPendingVAARequest.ProtoReflect.Descriptor instead.
+func (*ChainGovernorDropPendingVAARequest) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{16}
+}
+
+func (x *ChainGovernorDropPendingVAARequest) GetVaaId() string {
+	if x != nil {
+		return x.VaaId
+	}
+	return ""
+}
+
+type ChainGovernorDropPendingVAAResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Response string `protobuf:"bytes,1,opt,name=response,proto3" json:"response,omitempty"`
+}
+
+func (x *ChainGovernorDropPendingVAAResponse) Reset() {
+	*x = ChainGovernorDropPendingVAAResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[17]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorDropPendingVAAResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorDropPendingVAAResponse) ProtoMessage() {}
+
+func (x *ChainGovernorDropPendingVAAResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[17]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorDropPendingVAAResponse.ProtoReflect.Descriptor instead.
+func (*ChainGovernorDropPendingVAAResponse) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{17}
+}
+
+func (x *ChainGovernorDropPendingVAAResponse) GetResponse() string {
+	if x != nil {
+		return x.Response
+	}
+	return ""
+}
+
+type ChainGovernorReleasePendingVAARequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	VaaId string `protobuf:"bytes,1,opt,name=vaa_id,json=vaaId,proto3" json:"vaa_id,omitempty"`
+}
+
+func (x *ChainGovernorReleasePendingVAARequest) Reset() {
+	*x = ChainGovernorReleasePendingVAARequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[18]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorReleasePendingVAARequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorReleasePendingVAARequest) ProtoMessage() {}
+
+func (x *ChainGovernorReleasePendingVAARequest) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[18]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorReleasePendingVAARequest.ProtoReflect.Descriptor instead.
+func (*ChainGovernorReleasePendingVAARequest) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{18}
+}
+
+func (x *ChainGovernorReleasePendingVAARequest) GetVaaId() string {
+	if x != nil {
+		return x.VaaId
+	}
+	return ""
+}
+
+type ChainGovernorReleasePendingVAAResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Response string `protobuf:"bytes,1,opt,name=response,proto3" json:"response,omitempty"`
+}
+
+func (x *ChainGovernorReleasePendingVAAResponse) Reset() {
+	*x = ChainGovernorReleasePendingVAAResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[19]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorReleasePendingVAAResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorReleasePendingVAAResponse) ProtoMessage() {}
+
+func (x *ChainGovernorReleasePendingVAAResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[19]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorReleasePendingVAAResponse.ProtoReflect.Descriptor instead.
+func (*ChainGovernorReleasePendingVAAResponse) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{19}
+}
+
+func (x *ChainGovernorReleasePendingVAAResponse) GetResponse() string {
+	if x != nil {
+		return x.Response
+	}
+	return ""
+}
+
+type ChainGovernorResetReleaseTimerRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	VaaId string `protobuf:"bytes,1,opt,name=vaa_id,json=vaaId,proto3" json:"vaa_id,omitempty"`
+}
+
+func (x *ChainGovernorResetReleaseTimerRequest) Reset() {
+	*x = ChainGovernorResetReleaseTimerRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[20]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorResetReleaseTimerRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorResetReleaseTimerRequest) ProtoMessage() {}
+
+func (x *ChainGovernorResetReleaseTimerRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[20]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorResetReleaseTimerRequest.ProtoReflect.Descriptor instead.
+func (*ChainGovernorResetReleaseTimerRequest) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{20}
+}
+
+func (x *ChainGovernorResetReleaseTimerRequest) GetVaaId() string {
+	if x != nil {
+		return x.VaaId
+	}
+	return ""
+}
+
+type ChainGovernorResetReleaseTimerResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Response string `protobuf:"bytes,1,opt,name=response,proto3" json:"response,omitempty"`
+}
+
+func (x *ChainGovernorResetReleaseTimerResponse) Reset() {
+	*x = ChainGovernorResetReleaseTimerResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[21]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ChainGovernorResetReleaseTimerResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ChainGovernorResetReleaseTimerResponse) ProtoMessage() {}
+
+func (x *ChainGovernorResetReleaseTimerResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[21]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ChainGovernorResetReleaseTimerResponse.ProtoReflect.Descriptor instead.
+func (*ChainGovernorResetReleaseTimerResponse) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{21}
+}
+
+func (x *ChainGovernorResetReleaseTimerResponse) GetResponse() string {
+	if x != nil {
+		return x.Response
+	}
+	return ""
+}
+
+type PurgePythNetVaasRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	DaysOld uint64 `protobuf:"varint,1,opt,name=days_old,json=daysOld,proto3" json:"days_old,omitempty"`
+	LogOnly bool   `protobuf:"varint,2,opt,name=log_only,json=logOnly,proto3" json:"log_only,omitempty"`
+}
+
+func (x *PurgePythNetVaasRequest) Reset() {
+	*x = PurgePythNetVaasRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[22]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *PurgePythNetVaasRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PurgePythNetVaasRequest) ProtoMessage() {}
+
+func (x *PurgePythNetVaasRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[22]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use PurgePythNetVaasRequest.ProtoReflect.Descriptor instead.
+func (*PurgePythNetVaasRequest) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{22}
+}
+
+func (x *PurgePythNetVaasRequest) GetDaysOld() uint64 {
+	if x != nil {
+		return x.DaysOld
+	}
+	return 0
+}
+
+func (x *PurgePythNetVaasRequest) GetLogOnly() bool {
+	if x != nil {
+		return x.LogOnly
+	}
+	return false
+}
+
+type PurgePythNetVaasResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Response string `protobuf:"bytes,1,opt,name=response,proto3" json:"response,omitempty"`
+}
+
+func (x *PurgePythNetVaasResponse) Reset() {
+	*x = PurgePythNetVaasResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[23]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *PurgePythNetVaasResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PurgePythNetVaasResponse) ProtoMessage() {}
+
+func (x *PurgePythNetVaasResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[23]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use PurgePythNetVaasResponse.ProtoReflect.Descriptor instead.
+func (*PurgePythNetVaasResponse) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{23}
+}
+
+func (x *PurgePythNetVaasResponse) GetResponse() string {
+	if x != nil {
+		return x.Response
+	}
+	return ""
+}
+
+// List of guardian set members.
+type GuardianSetUpdate_Guardian struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Guardian key pubkey. Stored as hex string with 0x prefix for human readability -
+	// this is the canonical Ethereum representation.
+	Pubkey string `protobuf:"bytes,1,opt,name=pubkey,proto3" json:"pubkey,omitempty"`
+	// Optional descriptive name. Not stored on any chain, purely informational.
+	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *GuardianSetUpdate_Guardian) Reset() {
+	*x = GuardianSetUpdate_Guardian{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_node_v1_node_proto_msgTypes[24]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GuardianSetUpdate_Guardian) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GuardianSetUpdate_Guardian) ProtoMessage() {}
+
+func (x *GuardianSetUpdate_Guardian) ProtoReflect() protoreflect.Message {
+	mi := &file_node_v1_node_proto_msgTypes[24]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GuardianSetUpdate_Guardian.ProtoReflect.Descriptor instead.
+func (*GuardianSetUpdate_Guardian) Descriptor() ([]byte, []int) {
+	return file_node_v1_node_proto_rawDescGZIP(), []int{3, 0}
+}
+
+func (x *GuardianSetUpdate_Guardian) GetPubkey() string {
+	if x != nil {
+		return x.Pubkey
+	}
+	return ""
+}
+
+func (x *GuardianSetUpdate_Guardian) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+var File_node_v1_node_proto protoreflect.FileDescriptor
+
+var file_node_v1_node_proto_rawDesc = []byte{
+	0x0a, 0x12, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x16, 0x67,
+	0x6f, 0x73, 0x73, 0x69, 0x70, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9e, 0x01, 0x0a, 0x1a, 0x49, 0x6e, 0x6a, 0x65, 0x63, 0x74,
+	0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f,
+	0x73, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
+	0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78,
+	0x12, 0x36, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76,
+	0x65, 0x72, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08,
+	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x74, 0x69, 0x6d,
+	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x86, 0x03, 0x0a, 0x11, 0x47, 0x6f, 0x76, 0x65, 0x72,
+	0x6e, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08,
+	0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08,
+	0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63,
+	0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x3f,
+	0x0a, 0x0c, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x0a,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47,
+	0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+	0x48, 0x00, 0x52, 0x0b, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x12,
+	0x45, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x75, 0x70, 0x67, 0x72,
+	0x61, 0x64, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6e, 0x6f, 0x64, 0x65,
+	0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x55, 0x70, 0x67, 0x72,
+	0x61, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x55,
+	0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x12, 0x52, 0x0a, 0x15, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65,
+	0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18,
+	0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e,
+	0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x43, 0x68,
+	0x61, 0x69, 0x6e, 0x48, 0x00, 0x52, 0x13, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x67,
+	0x69, 0x73, 0x74, 0x65, 0x72, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x58, 0x0a, 0x17, 0x62, 0x72,
+	0x69, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x75, 0x70,
+	0x67, 0x72, 0x61, 0x64, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6e, 0x6f,
+	0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x55, 0x70, 0x67, 0x72,
+	0x61, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x48, 0x00, 0x52, 0x15, 0x62,
+	0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x55, 0x70, 0x67,
+	0x72, 0x61, 0x64, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22,
+	0x37, 0x0a, 0x1b, 0x49, 0x6e, 0x6a, 0x65, 0x63, 0x74, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x61,
+	0x6e, 0x63, 0x65, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18,
+	0x0a, 0x07, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52,
+	0x07, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x11, 0x47, 0x75, 0x61,
+	0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x41,
+	0x0a, 0x09, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x75, 0x61, 0x72,
+	0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x47, 0x75,
+	0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x52, 0x09, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e,
+	0x73, 0x1a, 0x36, 0x0a, 0x08, 0x47, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x12, 0x16, 0x0a,
+	0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70,
+	0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x5b, 0x0a, 0x0b, 0x47, 0x75, 0x61,
+	0x72, 0x64, 0x69, 0x61, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x38, 0x0a, 0x18,
+	0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x5f, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x69,
+	0x73, 0x74, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16,
+	0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x69, 0x73,
+	0x74, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x71, 0x0a, 0x13, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65,
+	0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x16, 0x0a,
+	0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d,
+	0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69,
+	0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64,
+	0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72,
+	0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6d, 0x69, 0x74, 0x74,
+	0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x4f, 0x0a, 0x0f, 0x43, 0x6f, 0x6e,
+	0x74, 0x72, 0x61, 0x63, 0x74, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x12, 0x19, 0x0a, 0x08,
+	0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
+	0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x63,
+	0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e,
+	0x65, 0x77, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x22, 0x7a, 0x0a, 0x15, 0x42, 0x72,
+	0x69, 0x64, 0x67, 0x65, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72,
+	0x61, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x74,
+	0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69,
+	0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72,
+	0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x43, 0x6f,
+	0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x22, 0xb4, 0x01, 0x0a, 0x1a, 0x46, 0x69, 0x6e, 0x64, 0x4d,
+	0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72,
+	0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6d,
+	0x69, 0x74, 0x74, 0x65, 0x72, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6d,
+	0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72,
+	0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x70, 0x63, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x66,
+	0x69, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x72, 0x70, 0x63, 0x42, 0x61,
+	0x63, 0x6b, 0x66, 0x69, 0x6c, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x66, 0x69,
+	0x6c, 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d,
+	0x62, 0x61, 0x63, 0x6b, 0x66, 0x69, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x94, 0x01,
+	0x0a, 0x1b, 0x46, 0x69, 0x6e, 0x64, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a,
+	0x10, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67,
+	0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x72, 0x73,
+	0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
+	0x52, 0x0d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12,
+	0x23, 0x0a, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x71, 0x75,
+	0x65, 0x6e, 0x63, 0x65, 0x22, 0x6f, 0x0a, 0x1d, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x62, 0x73, 0x65,
+	0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4e, 0x0a, 0x13, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4f,
+	0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x52, 0x12, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x20, 0x0a, 0x1e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x62, 0x73,
+	0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x43, 0x68, 0x61, 0x69, 0x6e,
+	0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x39, 0x0a, 0x1b, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f,
+	0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x22, 0x1c, 0x0a, 0x1a, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f,
+	0x72, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x39,
+	0x0a, 0x1b, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52,
+	0x65, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a,
+	0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x0a, 0x22, 0x43, 0x68, 0x61,
+	0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x44, 0x72, 0x6f, 0x70, 0x50, 0x65,
+	0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x15, 0x0a, 0x06, 0x76, 0x61, 0x61, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x05, 0x76, 0x61, 0x61, 0x49, 0x64, 0x22, 0x41, 0x0a, 0x23, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47,
+	0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x44, 0x72, 0x6f, 0x70, 0x50, 0x65, 0x6e, 0x64, 0x69,
+	0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a,
+	0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3e, 0x0a, 0x25, 0x43, 0x68, 0x61,
+	0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73,
+	0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x76, 0x61, 0x61, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x61, 0x49, 0x64, 0x22, 0x44, 0x0a, 0x26, 0x43, 0x68, 0x61,
+	0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73,
+	0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
+	0x3e, 0x0a, 0x25, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72,
+	0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65,
+	0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x76, 0x61, 0x61, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x61, 0x49, 0x64, 0x22,
+	0x44, 0x0a, 0x26, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72,
+	0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65,
+	0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x0a, 0x17, 0x50, 0x75, 0x72, 0x67, 0x65, 0x50, 0x79,
+	0x74, 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x19, 0x0a, 0x08, 0x64, 0x61, 0x79, 0x73, 0x5f, 0x6f, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x04, 0x52, 0x07, 0x64, 0x61, 0x79, 0x73, 0x4f, 0x6c, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6c,
+	0x6f, 0x67, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6c,
+	0x6f, 0x67, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x36, 0x0a, 0x18, 0x50, 0x75, 0x72, 0x67, 0x65, 0x50,
+	0x79, 0x74, 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe5,
+	0x07, 0x0a, 0x15, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65,
+	0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x49, 0x6e, 0x6a, 0x65,
+	0x63, 0x74, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x41, 0x41, 0x12,
+	0x23, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x6a, 0x65, 0x63, 0x74,
+	0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49,
+	0x6e, 0x6a, 0x65, 0x63, 0x74, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x56,
+	0x41, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x46, 0x69,
+	0x6e, 0x64, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x73, 0x12, 0x23, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64,
+	0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31,
+	0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x16,
+	0x53, 0x65, 0x6e, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31,
+	0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27,
+	0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x62, 0x73,
+	0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x43, 0x68, 0x61, 0x69, 0x6e,
+	0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23,
+	0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f,
+	0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68,
+	0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x43, 0x68, 0x61,
+	0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64,
+	0x12, 0x23, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e,
+	0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e,
+	0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c,
+	0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x1b, 0x43,
+	0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x44, 0x72, 0x6f, 0x70,
+	0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x12, 0x2b, 0x2e, 0x6e, 0x6f, 0x64,
+	0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e,
+	0x6f, 0x72, 0x44, 0x72, 0x6f, 0x70, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76,
+	0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x44,
+	0x72, 0x6f, 0x70, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x1e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47,
+	0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x50, 0x65,
+	0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x12, 0x2e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
+	0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72,
+	0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41,
+	0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
+	0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72,
+	0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41,
+	0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x1e, 0x43, 0x68,
+	0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x65, 0x74,
+	0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x2e, 0x2e, 0x6e,
+	0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65,
+	0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
+	0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6e,
+	0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65,
+	0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
+	0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a,
+	0x10, 0x50, 0x75, 0x72, 0x67, 0x65, 0x50, 0x79, 0x74, 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61,
+	0x73, 0x12, 0x20, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x67,
+	0x65, 0x50, 0x79, 0x74, 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75,
+	0x72, 0x67, 0x65, 0x50, 0x79, 0x74, 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61, 0x73, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
+	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x75, 0x73, 0x6f, 0x6e, 0x65, 0x2f, 0x77,
+	0x6f, 0x72, 0x6d, 0x68, 0x6f, 0x6c, 0x65, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67,
+	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6e,
+	0x6f, 0x64, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_node_v1_node_proto_rawDescOnce sync.Once
+	file_node_v1_node_proto_rawDescData = file_node_v1_node_proto_rawDesc
+)
+
+func file_node_v1_node_proto_rawDescGZIP() []byte {
+	file_node_v1_node_proto_rawDescOnce.Do(func() {
+		file_node_v1_node_proto_rawDescData = protoimpl.X.CompressGZIP(file_node_v1_node_proto_rawDescData)
+	})
+	return file_node_v1_node_proto_rawDescData
+}
+
+var file_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 25)
+var file_node_v1_node_proto_goTypes = []interface{}{
+	(*InjectGovernanceVAARequest)(nil),             // 0: node.v1.InjectGovernanceVAARequest
+	(*GovernanceMessage)(nil),                      // 1: node.v1.GovernanceMessage
+	(*InjectGovernanceVAAResponse)(nil),            // 2: node.v1.InjectGovernanceVAAResponse
+	(*GuardianSetUpdate)(nil),                      // 3: node.v1.GuardianSetUpdate
+	(*GuardianKey)(nil),                            // 4: node.v1.GuardianKey
+	(*BridgeRegisterChain)(nil),                    // 5: node.v1.BridgeRegisterChain
+	(*ContractUpgrade)(nil),                        // 6: node.v1.ContractUpgrade
+	(*BridgeUpgradeContract)(nil),                  // 7: node.v1.BridgeUpgradeContract
+	(*FindMissingMessagesRequest)(nil),             // 8: node.v1.FindMissingMessagesRequest
+	(*FindMissingMessagesResponse)(nil),            // 9: node.v1.FindMissingMessagesResponse
+	(*SendObservationRequestRequest)(nil),          // 10: node.v1.SendObservationRequestRequest
+	(*SendObservationRequestResponse)(nil),         // 11: node.v1.SendObservationRequestResponse
+	(*ChainGovernorStatusRequest)(nil),             // 12: node.v1.ChainGovernorStatusRequest
+	(*ChainGovernorStatusResponse)(nil),            // 13: node.v1.ChainGovernorStatusResponse
+	(*ChainGovernorReloadRequest)(nil),             // 14: node.v1.ChainGovernorReloadRequest
+	(*ChainGovernorReloadResponse)(nil),            // 15: node.v1.ChainGovernorReloadResponse
+	(*ChainGovernorDropPendingVAARequest)(nil),     // 16: node.v1.ChainGovernorDropPendingVAARequest
+	(*ChainGovernorDropPendingVAAResponse)(nil),    // 17: node.v1.ChainGovernorDropPendingVAAResponse
+	(*ChainGovernorReleasePendingVAARequest)(nil),  // 18: node.v1.ChainGovernorReleasePendingVAARequest
+	(*ChainGovernorReleasePendingVAAResponse)(nil), // 19: node.v1.ChainGovernorReleasePendingVAAResponse
+	(*ChainGovernorResetReleaseTimerRequest)(nil),  // 20: node.v1.ChainGovernorResetReleaseTimerRequest
+	(*ChainGovernorResetReleaseTimerResponse)(nil), // 21: node.v1.ChainGovernorResetReleaseTimerResponse
+	(*PurgePythNetVaasRequest)(nil),                // 22: node.v1.PurgePythNetVaasRequest
+	(*PurgePythNetVaasResponse)(nil),               // 23: node.v1.PurgePythNetVaasResponse
+	(*GuardianSetUpdate_Guardian)(nil),             // 24: node.v1.GuardianSetUpdate.Guardian
+	(*v1.ObservationRequest)(nil),                  // 25: gossip.v1.ObservationRequest
+}
+var file_node_v1_node_proto_depIdxs = []int32{
+	1,  // 0: node.v1.InjectGovernanceVAARequest.messages:type_name -> node.v1.GovernanceMessage
+	3,  // 1: node.v1.GovernanceMessage.guardian_set:type_name -> node.v1.GuardianSetUpdate
+	6,  // 2: node.v1.GovernanceMessage.contract_upgrade:type_name -> node.v1.ContractUpgrade
+	5,  // 3: node.v1.GovernanceMessage.bridge_register_chain:type_name -> node.v1.BridgeRegisterChain
+	7,  // 4: node.v1.GovernanceMessage.bridge_contract_upgrade:type_name -> node.v1.BridgeUpgradeContract
+	24, // 5: node.v1.GuardianSetUpdate.guardians:type_name -> node.v1.GuardianSetUpdate.Guardian
+	25, // 6: node.v1.SendObservationRequestRequest.observation_request:type_name -> gossip.v1.ObservationRequest
+	0,  // 7: node.v1.NodePrivilegedService.InjectGovernanceVAA:input_type -> node.v1.InjectGovernanceVAARequest
+	8,  // 8: node.v1.NodePrivilegedService.FindMissingMessages:input_type -> node.v1.FindMissingMessagesRequest
+	10, // 9: node.v1.NodePrivilegedService.SendObservationRequest:input_type -> node.v1.SendObservationRequestRequest
+	12, // 10: node.v1.NodePrivilegedService.ChainGovernorStatus:input_type -> node.v1.ChainGovernorStatusRequest
+	14, // 11: node.v1.NodePrivilegedService.ChainGovernorReload:input_type -> node.v1.ChainGovernorReloadRequest
+	16, // 12: node.v1.NodePrivilegedService.ChainGovernorDropPendingVAA:input_type -> node.v1.ChainGovernorDropPendingVAARequest
+	18, // 13: node.v1.NodePrivilegedService.ChainGovernorReleasePendingVAA:input_type -> node.v1.ChainGovernorReleasePendingVAARequest
+	20, // 14: node.v1.NodePrivilegedService.ChainGovernorResetReleaseTimer:input_type -> node.v1.ChainGovernorResetReleaseTimerRequest
+	22, // 15: node.v1.NodePrivilegedService.PurgePythNetVaas:input_type -> node.v1.PurgePythNetVaasRequest
+	2,  // 16: node.v1.NodePrivilegedService.InjectGovernanceVAA:output_type -> node.v1.InjectGovernanceVAAResponse
+	9,  // 17: node.v1.NodePrivilegedService.FindMissingMessages:output_type -> node.v1.FindMissingMessagesResponse
+	11, // 18: node.v1.NodePrivilegedService.SendObservationRequest:output_type -> node.v1.SendObservationRequestResponse
+	13, // 19: node.v1.NodePrivilegedService.ChainGovernorStatus:output_type -> node.v1.ChainGovernorStatusResponse
+	15, // 20: node.v1.NodePrivilegedService.ChainGovernorReload:output_type -> node.v1.ChainGovernorReloadResponse
+	17, // 21: node.v1.NodePrivilegedService.ChainGovernorDropPendingVAA:output_type -> node.v1.ChainGovernorDropPendingVAAResponse
+	19, // 22: node.v1.NodePrivilegedService.ChainGovernorReleasePendingVAA:output_type -> node.v1.ChainGovernorReleasePendingVAAResponse
+	21, // 23: node.v1.NodePrivilegedService.ChainGovernorResetReleaseTimer:output_type -> node.v1.ChainGovernorResetReleaseTimerResponse
+	23, // 24: node.v1.NodePrivilegedService.PurgePythNetVaas:output_type -> node.v1.PurgePythNetVaasResponse
+	16, // [16:25] is the sub-list for method output_type
+	7,  // [7:16] is the sub-list for method input_type
+	7,  // [7:7] is the sub-list for extension type_name
+	7,  // [7:7] is the sub-list for extension extendee
+	0,  // [0:7] is the sub-list for field type_name
+}
+
+func init() { file_node_v1_node_proto_init() }
+func file_node_v1_node_proto_init() {
+	if File_node_v1_node_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_node_v1_node_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InjectGovernanceVAARequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernanceMessage); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InjectGovernanceVAAResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GuardianSetUpdate); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GuardianKey); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*BridgeRegisterChain); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ContractUpgrade); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*BridgeUpgradeContract); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FindMissingMessagesRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FindMissingMessagesResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SendObservationRequestRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SendObservationRequestResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorStatusRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorStatusResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorReloadRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorReloadResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorDropPendingVAARequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorDropPendingVAAResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorReleasePendingVAARequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorReleasePendingVAAResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorResetReleaseTimerRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ChainGovernorResetReleaseTimerResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PurgePythNetVaasRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PurgePythNetVaasResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_node_v1_node_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GuardianSetUpdate_Guardian); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_node_v1_node_proto_msgTypes[1].OneofWrappers = []interface{}{
+		(*GovernanceMessage_GuardianSet)(nil),
+		(*GovernanceMessage_ContractUpgrade)(nil),
+		(*GovernanceMessage_BridgeRegisterChain)(nil),
+		(*GovernanceMessage_BridgeContractUpgrade)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_node_v1_node_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   25,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_node_v1_node_proto_goTypes,
+		DependencyIndexes: file_node_v1_node_proto_depIdxs,
+		MessageInfos:      file_node_v1_node_proto_msgTypes,
+	}.Build()
+	File_node_v1_node_proto = out.File
+	file_node_v1_node_proto_rawDesc = nil
+	file_node_v1_node_proto_goTypes = nil
+	file_node_v1_node_proto_depIdxs = nil
+}

+ 815 - 0
node/pkg/proto/node/v1/node.pb.gw.go

@@ -0,0 +1,815 @@
+// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
+// source: node/v1/node.proto
+
+/*
+Package nodev1 is a reverse proxy.
+
+It translates gRPC into RESTful JSON APIs.
+*/
+package nodev1
+
+import (
+	"context"
+	"io"
+	"net/http"
+
+	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+	"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/grpclog"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/grpc/status"
+	"google.golang.org/protobuf/proto"
+)
+
+// Suppress "imported and not used" errors
+var _ codes.Code
+var _ io.Reader
+var _ status.Status
+var _ = runtime.String
+var _ = utilities.NewDoubleArray
+var _ = metadata.Join
+
+func request_NodePrivilegedService_InjectGovernanceVAA_0(ctx context.Context, marshaler runtime.Marshaler, client NodePrivilegedServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq InjectGovernanceVAARequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.InjectGovernanceVAA(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_NodePrivilegedService_InjectGovernanceVAA_0(ctx context.Context, marshaler runtime.Marshaler, server NodePrivilegedServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq InjectGovernanceVAARequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.InjectGovernanceVAA(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_NodePrivilegedService_FindMissingMessages_0(ctx context.Context, marshaler runtime.Marshaler, client NodePrivilegedServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq FindMissingMessagesRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.FindMissingMessages(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_NodePrivilegedService_FindMissingMessages_0(ctx context.Context, marshaler runtime.Marshaler, server NodePrivilegedServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq FindMissingMessagesRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.FindMissingMessages(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_NodePrivilegedService_SendObservationRequest_0(ctx context.Context, marshaler runtime.Marshaler, client NodePrivilegedServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq SendObservationRequestRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.SendObservationRequest(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_NodePrivilegedService_SendObservationRequest_0(ctx context.Context, marshaler runtime.Marshaler, server NodePrivilegedServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq SendObservationRequestRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.SendObservationRequest(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_NodePrivilegedService_ChainGovernorStatus_0(ctx context.Context, marshaler runtime.Marshaler, client NodePrivilegedServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ChainGovernorStatusRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ChainGovernorStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_NodePrivilegedService_ChainGovernorStatus_0(ctx context.Context, marshaler runtime.Marshaler, server NodePrivilegedServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ChainGovernorStatusRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ChainGovernorStatus(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_NodePrivilegedService_ChainGovernorReload_0(ctx context.Context, marshaler runtime.Marshaler, client NodePrivilegedServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ChainGovernorReloadRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ChainGovernorReload(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_NodePrivilegedService_ChainGovernorReload_0(ctx context.Context, marshaler runtime.Marshaler, server NodePrivilegedServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ChainGovernorReloadRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ChainGovernorReload(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_NodePrivilegedService_ChainGovernorDropPendingVAA_0(ctx context.Context, marshaler runtime.Marshaler, client NodePrivilegedServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ChainGovernorDropPendingVAARequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ChainGovernorDropPendingVAA(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_NodePrivilegedService_ChainGovernorDropPendingVAA_0(ctx context.Context, marshaler runtime.Marshaler, server NodePrivilegedServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ChainGovernorDropPendingVAARequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ChainGovernorDropPendingVAA(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_NodePrivilegedService_ChainGovernorReleasePendingVAA_0(ctx context.Context, marshaler runtime.Marshaler, client NodePrivilegedServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ChainGovernorReleasePendingVAARequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ChainGovernorReleasePendingVAA(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_NodePrivilegedService_ChainGovernorReleasePendingVAA_0(ctx context.Context, marshaler runtime.Marshaler, server NodePrivilegedServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ChainGovernorReleasePendingVAARequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ChainGovernorReleasePendingVAA(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_NodePrivilegedService_ChainGovernorResetReleaseTimer_0(ctx context.Context, marshaler runtime.Marshaler, client NodePrivilegedServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ChainGovernorResetReleaseTimerRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ChainGovernorResetReleaseTimer(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_NodePrivilegedService_ChainGovernorResetReleaseTimer_0(ctx context.Context, marshaler runtime.Marshaler, server NodePrivilegedServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ChainGovernorResetReleaseTimerRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ChainGovernorResetReleaseTimer(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_NodePrivilegedService_PurgePythNetVaas_0(ctx context.Context, marshaler runtime.Marshaler, client NodePrivilegedServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq PurgePythNetVaasRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.PurgePythNetVaas(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_NodePrivilegedService_PurgePythNetVaas_0(ctx context.Context, marshaler runtime.Marshaler, server NodePrivilegedServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq PurgePythNetVaasRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.PurgePythNetVaas(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+// RegisterNodePrivilegedServiceHandlerServer registers the http handlers for service NodePrivilegedService to "mux".
+// UnaryRPC     :call NodePrivilegedServiceServer directly.
+// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
+// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterNodePrivilegedServiceHandlerFromEndpoint instead.
+func RegisterNodePrivilegedServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server NodePrivilegedServiceServer) error {
+
+	mux.Handle("POST", pattern_NodePrivilegedService_InjectGovernanceVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/node.v1.NodePrivilegedService/InjectGovernanceVAA", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/InjectGovernanceVAA"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_NodePrivilegedService_InjectGovernanceVAA_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_InjectGovernanceVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_FindMissingMessages_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/node.v1.NodePrivilegedService/FindMissingMessages", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/FindMissingMessages"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_NodePrivilegedService_FindMissingMessages_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_FindMissingMessages_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_SendObservationRequest_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/node.v1.NodePrivilegedService/SendObservationRequest", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/SendObservationRequest"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_NodePrivilegedService_SendObservationRequest_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_SendObservationRequest_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_ChainGovernorStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/node.v1.NodePrivilegedService/ChainGovernorStatus", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/ChainGovernorStatus"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_NodePrivilegedService_ChainGovernorStatus_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_ChainGovernorStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_ChainGovernorReload_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/node.v1.NodePrivilegedService/ChainGovernorReload", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/ChainGovernorReload"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_NodePrivilegedService_ChainGovernorReload_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_ChainGovernorReload_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_ChainGovernorDropPendingVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/node.v1.NodePrivilegedService/ChainGovernorDropPendingVAA", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/ChainGovernorDropPendingVAA"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_NodePrivilegedService_ChainGovernorDropPendingVAA_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_ChainGovernorDropPendingVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_ChainGovernorReleasePendingVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/node.v1.NodePrivilegedService/ChainGovernorReleasePendingVAA", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/ChainGovernorReleasePendingVAA"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_NodePrivilegedService_ChainGovernorReleasePendingVAA_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_ChainGovernorReleasePendingVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_ChainGovernorResetReleaseTimer_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/node.v1.NodePrivilegedService/ChainGovernorResetReleaseTimer", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/ChainGovernorResetReleaseTimer"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_NodePrivilegedService_ChainGovernorResetReleaseTimer_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_ChainGovernorResetReleaseTimer_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_PurgePythNetVaas_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/node.v1.NodePrivilegedService/PurgePythNetVaas", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/PurgePythNetVaas"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_NodePrivilegedService_PurgePythNetVaas_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_PurgePythNetVaas_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	return nil
+}
+
+// RegisterNodePrivilegedServiceHandlerFromEndpoint is same as RegisterNodePrivilegedServiceHandler but
+// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
+func RegisterNodePrivilegedServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
+	conn, err := grpc.Dial(endpoint, opts...)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		if err != nil {
+			if cerr := conn.Close(); cerr != nil {
+				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+			}
+			return
+		}
+		go func() {
+			<-ctx.Done()
+			if cerr := conn.Close(); cerr != nil {
+				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+			}
+		}()
+	}()
+
+	return RegisterNodePrivilegedServiceHandler(ctx, mux, conn)
+}
+
+// RegisterNodePrivilegedServiceHandler registers the http handlers for service NodePrivilegedService to "mux".
+// The handlers forward requests to the grpc endpoint over "conn".
+func RegisterNodePrivilegedServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+	return RegisterNodePrivilegedServiceHandlerClient(ctx, mux, NewNodePrivilegedServiceClient(conn))
+}
+
+// RegisterNodePrivilegedServiceHandlerClient registers the http handlers for service NodePrivilegedService
+// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "NodePrivilegedServiceClient".
+// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "NodePrivilegedServiceClient"
+// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
+// "NodePrivilegedServiceClient" to call the correct interceptors.
+func RegisterNodePrivilegedServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client NodePrivilegedServiceClient) error {
+
+	mux.Handle("POST", pattern_NodePrivilegedService_InjectGovernanceVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/node.v1.NodePrivilegedService/InjectGovernanceVAA", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/InjectGovernanceVAA"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_NodePrivilegedService_InjectGovernanceVAA_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_InjectGovernanceVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_FindMissingMessages_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/node.v1.NodePrivilegedService/FindMissingMessages", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/FindMissingMessages"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_NodePrivilegedService_FindMissingMessages_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_FindMissingMessages_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_SendObservationRequest_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/node.v1.NodePrivilegedService/SendObservationRequest", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/SendObservationRequest"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_NodePrivilegedService_SendObservationRequest_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_SendObservationRequest_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_ChainGovernorStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/node.v1.NodePrivilegedService/ChainGovernorStatus", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/ChainGovernorStatus"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_NodePrivilegedService_ChainGovernorStatus_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_ChainGovernorStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_ChainGovernorReload_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/node.v1.NodePrivilegedService/ChainGovernorReload", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/ChainGovernorReload"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_NodePrivilegedService_ChainGovernorReload_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_ChainGovernorReload_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_ChainGovernorDropPendingVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/node.v1.NodePrivilegedService/ChainGovernorDropPendingVAA", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/ChainGovernorDropPendingVAA"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_NodePrivilegedService_ChainGovernorDropPendingVAA_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_ChainGovernorDropPendingVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_ChainGovernorReleasePendingVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/node.v1.NodePrivilegedService/ChainGovernorReleasePendingVAA", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/ChainGovernorReleasePendingVAA"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_NodePrivilegedService_ChainGovernorReleasePendingVAA_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_ChainGovernorReleasePendingVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_ChainGovernorResetReleaseTimer_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/node.v1.NodePrivilegedService/ChainGovernorResetReleaseTimer", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/ChainGovernorResetReleaseTimer"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_NodePrivilegedService_ChainGovernorResetReleaseTimer_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_ChainGovernorResetReleaseTimer_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_NodePrivilegedService_PurgePythNetVaas_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/node.v1.NodePrivilegedService/PurgePythNetVaas", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/PurgePythNetVaas"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_NodePrivilegedService_PurgePythNetVaas_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_NodePrivilegedService_PurgePythNetVaas_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	return nil
+}
+
+var (
+	pattern_NodePrivilegedService_InjectGovernanceVAA_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "InjectGovernanceVAA"}, ""))
+
+	pattern_NodePrivilegedService_FindMissingMessages_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "FindMissingMessages"}, ""))
+
+	pattern_NodePrivilegedService_SendObservationRequest_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "SendObservationRequest"}, ""))
+
+	pattern_NodePrivilegedService_ChainGovernorStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "ChainGovernorStatus"}, ""))
+
+	pattern_NodePrivilegedService_ChainGovernorReload_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "ChainGovernorReload"}, ""))
+
+	pattern_NodePrivilegedService_ChainGovernorDropPendingVAA_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "ChainGovernorDropPendingVAA"}, ""))
+
+	pattern_NodePrivilegedService_ChainGovernorReleasePendingVAA_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "ChainGovernorReleasePendingVAA"}, ""))
+
+	pattern_NodePrivilegedService_ChainGovernorResetReleaseTimer_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "ChainGovernorResetReleaseTimer"}, ""))
+
+	pattern_NodePrivilegedService_PurgePythNetVaas_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "PurgePythNetVaas"}, ""))
+)
+
+var (
+	forward_NodePrivilegedService_InjectGovernanceVAA_0 = runtime.ForwardResponseMessage
+
+	forward_NodePrivilegedService_FindMissingMessages_0 = runtime.ForwardResponseMessage
+
+	forward_NodePrivilegedService_SendObservationRequest_0 = runtime.ForwardResponseMessage
+
+	forward_NodePrivilegedService_ChainGovernorStatus_0 = runtime.ForwardResponseMessage
+
+	forward_NodePrivilegedService_ChainGovernorReload_0 = runtime.ForwardResponseMessage
+
+	forward_NodePrivilegedService_ChainGovernorDropPendingVAA_0 = runtime.ForwardResponseMessage
+
+	forward_NodePrivilegedService_ChainGovernorReleasePendingVAA_0 = runtime.ForwardResponseMessage
+
+	forward_NodePrivilegedService_ChainGovernorResetReleaseTimer_0 = runtime.ForwardResponseMessage
+
+	forward_NodePrivilegedService_PurgePythNetVaas_0 = runtime.ForwardResponseMessage
+)

+ 429 - 0
node/pkg/proto/node/v1/node_grpc.pb.go

@@ -0,0 +1,429 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package nodev1
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+// NodePrivilegedServiceClient is the client API for NodePrivilegedService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type NodePrivilegedServiceClient interface {
+	// InjectGovernanceVAA injects a governance VAA into the guardian node.
+	// The node will inject the VAA into the aggregator and sign/broadcast the VAA signature.
+	//
+	// A consensus majority of nodes on the network will have to inject the VAA within the
+	// VAA timeout window for it to reach consensus.
+	//
+	InjectGovernanceVAA(ctx context.Context, in *InjectGovernanceVAARequest, opts ...grpc.CallOption) (*InjectGovernanceVAAResponse, error)
+	// FindMissingMessages will detect message sequence gaps in the local VAA store for a
+	// specific emitter chain and address. Start and end slots are the lowest and highest
+	// sequence numbers available in the local store, respectively.
+	//
+	// An error is returned if more than 1000 gaps are found.
+	FindMissingMessages(ctx context.Context, in *FindMissingMessagesRequest, opts ...grpc.CallOption) (*FindMissingMessagesResponse, error)
+	// SendObservationRequest broadcasts a signed observation request to the gossip network
+	// using the node's guardian key. The network rate limits these requests to one per second.
+	// Requests at higher rates will fail silently.
+	SendObservationRequest(ctx context.Context, in *SendObservationRequestRequest, opts ...grpc.CallOption) (*SendObservationRequestResponse, error)
+	// ChainGovernorStatus displays the status of the chain governor.
+	ChainGovernorStatus(ctx context.Context, in *ChainGovernorStatusRequest, opts ...grpc.CallOption) (*ChainGovernorStatusResponse, error)
+	// ChainGovernorReload clears the chain governor history and reloads it from the database.
+	ChainGovernorReload(ctx context.Context, in *ChainGovernorReloadRequest, opts ...grpc.CallOption) (*ChainGovernorReloadResponse, error)
+	// ChainGovernorDropPendingVAA drops a VAA from the chain governor pending list.
+	ChainGovernorDropPendingVAA(ctx context.Context, in *ChainGovernorDropPendingVAARequest, opts ...grpc.CallOption) (*ChainGovernorDropPendingVAAResponse, error)
+	// ChainGovernorReleasePendingVAA release a VAA from the chain governor pending list, publishing it immediately.
+	ChainGovernorReleasePendingVAA(ctx context.Context, in *ChainGovernorReleasePendingVAARequest, opts ...grpc.CallOption) (*ChainGovernorReleasePendingVAAResponse, error)
+	// ChainGovernorResetReleaseTimer resets the release timer for a chain governor pending VAA to the configured maximum.
+	ChainGovernorResetReleaseTimer(ctx context.Context, in *ChainGovernorResetReleaseTimerRequest, opts ...grpc.CallOption) (*ChainGovernorResetReleaseTimerResponse, error)
+	// PurgePythNetVaas deletes PythNet VAAs from the database that are more than the specified number of days old.
+	PurgePythNetVaas(ctx context.Context, in *PurgePythNetVaasRequest, opts ...grpc.CallOption) (*PurgePythNetVaasResponse, error)
+}
+
+type nodePrivilegedServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewNodePrivilegedServiceClient(cc grpc.ClientConnInterface) NodePrivilegedServiceClient {
+	return &nodePrivilegedServiceClient{cc}
+}
+
+func (c *nodePrivilegedServiceClient) InjectGovernanceVAA(ctx context.Context, in *InjectGovernanceVAARequest, opts ...grpc.CallOption) (*InjectGovernanceVAAResponse, error) {
+	out := new(InjectGovernanceVAAResponse)
+	err := c.cc.Invoke(ctx, "/node.v1.NodePrivilegedService/InjectGovernanceVAA", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *nodePrivilegedServiceClient) FindMissingMessages(ctx context.Context, in *FindMissingMessagesRequest, opts ...grpc.CallOption) (*FindMissingMessagesResponse, error) {
+	out := new(FindMissingMessagesResponse)
+	err := c.cc.Invoke(ctx, "/node.v1.NodePrivilegedService/FindMissingMessages", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *nodePrivilegedServiceClient) SendObservationRequest(ctx context.Context, in *SendObservationRequestRequest, opts ...grpc.CallOption) (*SendObservationRequestResponse, error) {
+	out := new(SendObservationRequestResponse)
+	err := c.cc.Invoke(ctx, "/node.v1.NodePrivilegedService/SendObservationRequest", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *nodePrivilegedServiceClient) ChainGovernorStatus(ctx context.Context, in *ChainGovernorStatusRequest, opts ...grpc.CallOption) (*ChainGovernorStatusResponse, error) {
+	out := new(ChainGovernorStatusResponse)
+	err := c.cc.Invoke(ctx, "/node.v1.NodePrivilegedService/ChainGovernorStatus", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *nodePrivilegedServiceClient) ChainGovernorReload(ctx context.Context, in *ChainGovernorReloadRequest, opts ...grpc.CallOption) (*ChainGovernorReloadResponse, error) {
+	out := new(ChainGovernorReloadResponse)
+	err := c.cc.Invoke(ctx, "/node.v1.NodePrivilegedService/ChainGovernorReload", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *nodePrivilegedServiceClient) ChainGovernorDropPendingVAA(ctx context.Context, in *ChainGovernorDropPendingVAARequest, opts ...grpc.CallOption) (*ChainGovernorDropPendingVAAResponse, error) {
+	out := new(ChainGovernorDropPendingVAAResponse)
+	err := c.cc.Invoke(ctx, "/node.v1.NodePrivilegedService/ChainGovernorDropPendingVAA", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *nodePrivilegedServiceClient) ChainGovernorReleasePendingVAA(ctx context.Context, in *ChainGovernorReleasePendingVAARequest, opts ...grpc.CallOption) (*ChainGovernorReleasePendingVAAResponse, error) {
+	out := new(ChainGovernorReleasePendingVAAResponse)
+	err := c.cc.Invoke(ctx, "/node.v1.NodePrivilegedService/ChainGovernorReleasePendingVAA", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *nodePrivilegedServiceClient) ChainGovernorResetReleaseTimer(ctx context.Context, in *ChainGovernorResetReleaseTimerRequest, opts ...grpc.CallOption) (*ChainGovernorResetReleaseTimerResponse, error) {
+	out := new(ChainGovernorResetReleaseTimerResponse)
+	err := c.cc.Invoke(ctx, "/node.v1.NodePrivilegedService/ChainGovernorResetReleaseTimer", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *nodePrivilegedServiceClient) PurgePythNetVaas(ctx context.Context, in *PurgePythNetVaasRequest, opts ...grpc.CallOption) (*PurgePythNetVaasResponse, error) {
+	out := new(PurgePythNetVaasResponse)
+	err := c.cc.Invoke(ctx, "/node.v1.NodePrivilegedService/PurgePythNetVaas", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// NodePrivilegedServiceServer is the server API for NodePrivilegedService service.
+// All implementations must embed UnimplementedNodePrivilegedServiceServer
+// for forward compatibility
+type NodePrivilegedServiceServer interface {
+	// InjectGovernanceVAA injects a governance VAA into the guardian node.
+	// The node will inject the VAA into the aggregator and sign/broadcast the VAA signature.
+	//
+	// A consensus majority of nodes on the network will have to inject the VAA within the
+	// VAA timeout window for it to reach consensus.
+	//
+	InjectGovernanceVAA(context.Context, *InjectGovernanceVAARequest) (*InjectGovernanceVAAResponse, error)
+	// FindMissingMessages will detect message sequence gaps in the local VAA store for a
+	// specific emitter chain and address. Start and end slots are the lowest and highest
+	// sequence numbers available in the local store, respectively.
+	//
+	// An error is returned if more than 1000 gaps are found.
+	FindMissingMessages(context.Context, *FindMissingMessagesRequest) (*FindMissingMessagesResponse, error)
+	// SendObservationRequest broadcasts a signed observation request to the gossip network
+	// using the node's guardian key. The network rate limits these requests to one per second.
+	// Requests at higher rates will fail silently.
+	SendObservationRequest(context.Context, *SendObservationRequestRequest) (*SendObservationRequestResponse, error)
+	// ChainGovernorStatus displays the status of the chain governor.
+	ChainGovernorStatus(context.Context, *ChainGovernorStatusRequest) (*ChainGovernorStatusResponse, error)
+	// ChainGovernorReload clears the chain governor history and reloads it from the database.
+	ChainGovernorReload(context.Context, *ChainGovernorReloadRequest) (*ChainGovernorReloadResponse, error)
+	// ChainGovernorDropPendingVAA drops a VAA from the chain governor pending list.
+	ChainGovernorDropPendingVAA(context.Context, *ChainGovernorDropPendingVAARequest) (*ChainGovernorDropPendingVAAResponse, error)
+	// ChainGovernorReleasePendingVAA release a VAA from the chain governor pending list, publishing it immediately.
+	ChainGovernorReleasePendingVAA(context.Context, *ChainGovernorReleasePendingVAARequest) (*ChainGovernorReleasePendingVAAResponse, error)
+	// ChainGovernorResetReleaseTimer resets the release timer for a chain governor pending VAA to the configured maximum.
+	ChainGovernorResetReleaseTimer(context.Context, *ChainGovernorResetReleaseTimerRequest) (*ChainGovernorResetReleaseTimerResponse, error)
+	// PurgePythNetVaas deletes PythNet VAAs from the database that are more than the specified number of days old.
+	PurgePythNetVaas(context.Context, *PurgePythNetVaasRequest) (*PurgePythNetVaasResponse, error)
+	mustEmbedUnimplementedNodePrivilegedServiceServer()
+}
+
+// UnimplementedNodePrivilegedServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedNodePrivilegedServiceServer struct {
+}
+
+func (UnimplementedNodePrivilegedServiceServer) InjectGovernanceVAA(context.Context, *InjectGovernanceVAARequest) (*InjectGovernanceVAAResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method InjectGovernanceVAA not implemented")
+}
+func (UnimplementedNodePrivilegedServiceServer) FindMissingMessages(context.Context, *FindMissingMessagesRequest) (*FindMissingMessagesResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method FindMissingMessages not implemented")
+}
+func (UnimplementedNodePrivilegedServiceServer) SendObservationRequest(context.Context, *SendObservationRequestRequest) (*SendObservationRequestResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SendObservationRequest not implemented")
+}
+func (UnimplementedNodePrivilegedServiceServer) ChainGovernorStatus(context.Context, *ChainGovernorStatusRequest) (*ChainGovernorStatusResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ChainGovernorStatus not implemented")
+}
+func (UnimplementedNodePrivilegedServiceServer) ChainGovernorReload(context.Context, *ChainGovernorReloadRequest) (*ChainGovernorReloadResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ChainGovernorReload not implemented")
+}
+func (UnimplementedNodePrivilegedServiceServer) ChainGovernorDropPendingVAA(context.Context, *ChainGovernorDropPendingVAARequest) (*ChainGovernorDropPendingVAAResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ChainGovernorDropPendingVAA not implemented")
+}
+func (UnimplementedNodePrivilegedServiceServer) ChainGovernorReleasePendingVAA(context.Context, *ChainGovernorReleasePendingVAARequest) (*ChainGovernorReleasePendingVAAResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ChainGovernorReleasePendingVAA not implemented")
+}
+func (UnimplementedNodePrivilegedServiceServer) ChainGovernorResetReleaseTimer(context.Context, *ChainGovernorResetReleaseTimerRequest) (*ChainGovernorResetReleaseTimerResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ChainGovernorResetReleaseTimer not implemented")
+}
+func (UnimplementedNodePrivilegedServiceServer) PurgePythNetVaas(context.Context, *PurgePythNetVaasRequest) (*PurgePythNetVaasResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method PurgePythNetVaas not implemented")
+}
+func (UnimplementedNodePrivilegedServiceServer) mustEmbedUnimplementedNodePrivilegedServiceServer() {}
+
+// UnsafeNodePrivilegedServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to NodePrivilegedServiceServer will
+// result in compilation errors.
+type UnsafeNodePrivilegedServiceServer interface {
+	mustEmbedUnimplementedNodePrivilegedServiceServer()
+}
+
+func RegisterNodePrivilegedServiceServer(s grpc.ServiceRegistrar, srv NodePrivilegedServiceServer) {
+	s.RegisterService(&NodePrivilegedService_ServiceDesc, srv)
+}
+
+func _NodePrivilegedService_InjectGovernanceVAA_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(InjectGovernanceVAARequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(NodePrivilegedServiceServer).InjectGovernanceVAA(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/node.v1.NodePrivilegedService/InjectGovernanceVAA",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(NodePrivilegedServiceServer).InjectGovernanceVAA(ctx, req.(*InjectGovernanceVAARequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _NodePrivilegedService_FindMissingMessages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(FindMissingMessagesRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(NodePrivilegedServiceServer).FindMissingMessages(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/node.v1.NodePrivilegedService/FindMissingMessages",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(NodePrivilegedServiceServer).FindMissingMessages(ctx, req.(*FindMissingMessagesRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _NodePrivilegedService_SendObservationRequest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(SendObservationRequestRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(NodePrivilegedServiceServer).SendObservationRequest(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/node.v1.NodePrivilegedService/SendObservationRequest",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(NodePrivilegedServiceServer).SendObservationRequest(ctx, req.(*SendObservationRequestRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _NodePrivilegedService_ChainGovernorStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ChainGovernorStatusRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(NodePrivilegedServiceServer).ChainGovernorStatus(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/node.v1.NodePrivilegedService/ChainGovernorStatus",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(NodePrivilegedServiceServer).ChainGovernorStatus(ctx, req.(*ChainGovernorStatusRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _NodePrivilegedService_ChainGovernorReload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ChainGovernorReloadRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(NodePrivilegedServiceServer).ChainGovernorReload(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/node.v1.NodePrivilegedService/ChainGovernorReload",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(NodePrivilegedServiceServer).ChainGovernorReload(ctx, req.(*ChainGovernorReloadRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _NodePrivilegedService_ChainGovernorDropPendingVAA_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ChainGovernorDropPendingVAARequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(NodePrivilegedServiceServer).ChainGovernorDropPendingVAA(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/node.v1.NodePrivilegedService/ChainGovernorDropPendingVAA",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(NodePrivilegedServiceServer).ChainGovernorDropPendingVAA(ctx, req.(*ChainGovernorDropPendingVAARequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _NodePrivilegedService_ChainGovernorReleasePendingVAA_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ChainGovernorReleasePendingVAARequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(NodePrivilegedServiceServer).ChainGovernorReleasePendingVAA(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/node.v1.NodePrivilegedService/ChainGovernorReleasePendingVAA",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(NodePrivilegedServiceServer).ChainGovernorReleasePendingVAA(ctx, req.(*ChainGovernorReleasePendingVAARequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _NodePrivilegedService_ChainGovernorResetReleaseTimer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ChainGovernorResetReleaseTimerRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(NodePrivilegedServiceServer).ChainGovernorResetReleaseTimer(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/node.v1.NodePrivilegedService/ChainGovernorResetReleaseTimer",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(NodePrivilegedServiceServer).ChainGovernorResetReleaseTimer(ctx, req.(*ChainGovernorResetReleaseTimerRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _NodePrivilegedService_PurgePythNetVaas_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(PurgePythNetVaasRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(NodePrivilegedServiceServer).PurgePythNetVaas(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/node.v1.NodePrivilegedService/PurgePythNetVaas",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(NodePrivilegedServiceServer).PurgePythNetVaas(ctx, req.(*PurgePythNetVaasRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// NodePrivilegedService_ServiceDesc is the grpc.ServiceDesc for NodePrivilegedService service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var NodePrivilegedService_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "node.v1.NodePrivilegedService",
+	HandlerType: (*NodePrivilegedServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "InjectGovernanceVAA",
+			Handler:    _NodePrivilegedService_InjectGovernanceVAA_Handler,
+		},
+		{
+			MethodName: "FindMissingMessages",
+			Handler:    _NodePrivilegedService_FindMissingMessages_Handler,
+		},
+		{
+			MethodName: "SendObservationRequest",
+			Handler:    _NodePrivilegedService_SendObservationRequest_Handler,
+		},
+		{
+			MethodName: "ChainGovernorStatus",
+			Handler:    _NodePrivilegedService_ChainGovernorStatus_Handler,
+		},
+		{
+			MethodName: "ChainGovernorReload",
+			Handler:    _NodePrivilegedService_ChainGovernorReload_Handler,
+		},
+		{
+			MethodName: "ChainGovernorDropPendingVAA",
+			Handler:    _NodePrivilegedService_ChainGovernorDropPendingVAA_Handler,
+		},
+		{
+			MethodName: "ChainGovernorReleasePendingVAA",
+			Handler:    _NodePrivilegedService_ChainGovernorReleasePendingVAA_Handler,
+		},
+		{
+			MethodName: "ChainGovernorResetReleaseTimer",
+			Handler:    _NodePrivilegedService_ChainGovernorResetReleaseTimer_Handler,
+		},
+		{
+			MethodName: "PurgePythNetVaas",
+			Handler:    _NodePrivilegedService_PurgePythNetVaas_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "node/v1/node.proto",
+}

+ 1986 - 0
node/pkg/proto/publicrpc/v1/publicrpc.pb.go

@@ -0,0 +1,1986 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.27.1
+// 	protoc        (unknown)
+// source: publicrpc/v1/publicrpc.proto
+
+package publicrpcv1
+
+import (
+	v1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1"
+	_ "google.golang.org/genproto/googleapis/api/annotations"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type ChainID int32
+
+const (
+	ChainID_CHAIN_ID_UNSPECIFIED ChainID = 0
+	ChainID_CHAIN_ID_SOLANA      ChainID = 1
+	ChainID_CHAIN_ID_ETHEREUM    ChainID = 2
+	ChainID_CHAIN_ID_TERRA       ChainID = 3
+	ChainID_CHAIN_ID_BSC         ChainID = 4
+	ChainID_CHAIN_ID_POLYGON     ChainID = 5
+	ChainID_CHAIN_ID_AVALANCHE   ChainID = 6
+	ChainID_CHAIN_ID_OASIS       ChainID = 7
+	ChainID_CHAIN_ID_ALGORAND    ChainID = 8
+	ChainID_CHAIN_ID_AURORA      ChainID = 9
+	ChainID_CHAIN_ID_FANTOM      ChainID = 10
+	ChainID_CHAIN_ID_KARURA      ChainID = 11
+	ChainID_CHAIN_ID_ACALA       ChainID = 12
+	ChainID_CHAIN_ID_KLAYTN      ChainID = 13
+	ChainID_CHAIN_ID_CELO        ChainID = 14
+	ChainID_CHAIN_ID_NEAR        ChainID = 15
+	ChainID_CHAIN_ID_MOONBEAM    ChainID = 16
+	ChainID_CHAIN_ID_NEON        ChainID = 17
+	ChainID_CHAIN_ID_TERRA2      ChainID = 18
+	ChainID_CHAIN_ID_INJECTIVE   ChainID = 19
+	ChainID_CHAIN_ID_OSMOSIS     ChainID = 20
+	ChainID_CHAIN_ID_SUI         ChainID = 21
+	ChainID_CHAIN_ID_APTOS       ChainID = 22
+	ChainID_CHAIN_ID_ARBITRUM    ChainID = 23
+	ChainID_CHAIN_ID_OPTIMISM    ChainID = 24
+	ChainID_CHAIN_ID_GNOSIS      ChainID = 25
+	ChainID_CHAIN_ID_PYTHNET     ChainID = 26
+	ChainID_CHAIN_ID_XPLA        ChainID = 28
+)
+
+// Enum value maps for ChainID.
+var (
+	ChainID_name = map[int32]string{
+		0:  "CHAIN_ID_UNSPECIFIED",
+		1:  "CHAIN_ID_SOLANA",
+		2:  "CHAIN_ID_ETHEREUM",
+		3:  "CHAIN_ID_TERRA",
+		4:  "CHAIN_ID_BSC",
+		5:  "CHAIN_ID_POLYGON",
+		6:  "CHAIN_ID_AVALANCHE",
+		7:  "CHAIN_ID_OASIS",
+		8:  "CHAIN_ID_ALGORAND",
+		9:  "CHAIN_ID_AURORA",
+		10: "CHAIN_ID_FANTOM",
+		11: "CHAIN_ID_KARURA",
+		12: "CHAIN_ID_ACALA",
+		13: "CHAIN_ID_KLAYTN",
+		14: "CHAIN_ID_CELO",
+		15: "CHAIN_ID_NEAR",
+		16: "CHAIN_ID_MOONBEAM",
+		17: "CHAIN_ID_NEON",
+		18: "CHAIN_ID_TERRA2",
+		19: "CHAIN_ID_INJECTIVE",
+		20: "CHAIN_ID_OSMOSIS",
+		21: "CHAIN_ID_SUI",
+		22: "CHAIN_ID_APTOS",
+		23: "CHAIN_ID_ARBITRUM",
+		24: "CHAIN_ID_OPTIMISM",
+		25: "CHAIN_ID_GNOSIS",
+		26: "CHAIN_ID_PYTHNET",
+		28: "CHAIN_ID_XPLA",
+	}
+	ChainID_value = map[string]int32{
+		"CHAIN_ID_UNSPECIFIED": 0,
+		"CHAIN_ID_SOLANA":      1,
+		"CHAIN_ID_ETHEREUM":    2,
+		"CHAIN_ID_TERRA":       3,
+		"CHAIN_ID_BSC":         4,
+		"CHAIN_ID_POLYGON":     5,
+		"CHAIN_ID_AVALANCHE":   6,
+		"CHAIN_ID_OASIS":       7,
+		"CHAIN_ID_ALGORAND":    8,
+		"CHAIN_ID_AURORA":      9,
+		"CHAIN_ID_FANTOM":      10,
+		"CHAIN_ID_KARURA":      11,
+		"CHAIN_ID_ACALA":       12,
+		"CHAIN_ID_KLAYTN":      13,
+		"CHAIN_ID_CELO":        14,
+		"CHAIN_ID_NEAR":        15,
+		"CHAIN_ID_MOONBEAM":    16,
+		"CHAIN_ID_NEON":        17,
+		"CHAIN_ID_TERRA2":      18,
+		"CHAIN_ID_INJECTIVE":   19,
+		"CHAIN_ID_OSMOSIS":     20,
+		"CHAIN_ID_SUI":         21,
+		"CHAIN_ID_APTOS":       22,
+		"CHAIN_ID_ARBITRUM":    23,
+		"CHAIN_ID_OPTIMISM":    24,
+		"CHAIN_ID_GNOSIS":      25,
+		"CHAIN_ID_PYTHNET":     26,
+		"CHAIN_ID_XPLA":        28,
+	}
+)
+
+func (x ChainID) Enum() *ChainID {
+	p := new(ChainID)
+	*p = x
+	return p
+}
+
+func (x ChainID) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ChainID) Descriptor() protoreflect.EnumDescriptor {
+	return file_publicrpc_v1_publicrpc_proto_enumTypes[0].Descriptor()
+}
+
+func (ChainID) Type() protoreflect.EnumType {
+	return &file_publicrpc_v1_publicrpc_proto_enumTypes[0]
+}
+
+func (x ChainID) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ChainID.Descriptor instead.
+func (ChainID) EnumDescriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{0}
+}
+
+// MessageID is a VAA's globally unique identifier (see data availability design document).
+type MessageID struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Emitter chain ID.
+	EmitterChain ChainID `protobuf:"varint,1,opt,name=emitter_chain,json=emitterChain,proto3,enum=publicrpc.v1.ChainID" json:"emitter_chain,omitempty"`
+	// Hex-encoded (without leading 0x) emitter address.
+	EmitterAddress string `protobuf:"bytes,2,opt,name=emitter_address,json=emitterAddress,proto3" json:"emitter_address,omitempty"`
+	// Sequence number for (emitter_chain, emitter_address).
+	Sequence uint64 `protobuf:"varint,3,opt,name=sequence,proto3" json:"sequence,omitempty"`
+}
+
+func (x *MessageID) Reset() {
+	*x = MessageID{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MessageID) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MessageID) ProtoMessage() {}
+
+func (x *MessageID) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MessageID.ProtoReflect.Descriptor instead.
+func (*MessageID) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *MessageID) GetEmitterChain() ChainID {
+	if x != nil {
+		return x.EmitterChain
+	}
+	return ChainID_CHAIN_ID_UNSPECIFIED
+}
+
+func (x *MessageID) GetEmitterAddress() string {
+	if x != nil {
+		return x.EmitterAddress
+	}
+	return ""
+}
+
+func (x *MessageID) GetSequence() uint64 {
+	if x != nil {
+		return x.Sequence
+	}
+	return 0
+}
+
+type BatchID struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Emitter chain ID.
+	EmitterChain ChainID `protobuf:"varint,1,opt,name=emitter_chain,json=emitterChain,proto3,enum=publicrpc.v1.ChainID" json:"emitter_chain,omitempty"`
+	// Hex-encoded (without leading 0x) transaction identifier.
+	TxId string `protobuf:"bytes,2,opt,name=tx_id,json=txId,proto3" json:"tx_id,omitempty"`
+}
+
+func (x *BatchID) Reset() {
+	*x = BatchID{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *BatchID) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BatchID) ProtoMessage() {}
+
+func (x *BatchID) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use BatchID.ProtoReflect.Descriptor instead.
+func (*BatchID) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *BatchID) GetEmitterChain() ChainID {
+	if x != nil {
+		return x.EmitterChain
+	}
+	return ChainID_CHAIN_ID_UNSPECIFIED
+}
+
+func (x *BatchID) GetTxId() string {
+	if x != nil {
+		return x.TxId
+	}
+	return ""
+}
+
+type GetSignedVAARequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	MessageId *MessageID `protobuf:"bytes,1,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"`
+}
+
+func (x *GetSignedVAARequest) Reset() {
+	*x = GetSignedVAARequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetSignedVAARequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetSignedVAARequest) ProtoMessage() {}
+
+func (x *GetSignedVAARequest) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetSignedVAARequest.ProtoReflect.Descriptor instead.
+func (*GetSignedVAARequest) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *GetSignedVAARequest) GetMessageId() *MessageID {
+	if x != nil {
+		return x.MessageId
+	}
+	return nil
+}
+
+type GetSignedVAAResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	VaaBytes []byte `protobuf:"bytes,1,opt,name=vaa_bytes,json=vaaBytes,proto3" json:"vaa_bytes,omitempty"`
+}
+
+func (x *GetSignedVAAResponse) Reset() {
+	*x = GetSignedVAAResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetSignedVAAResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetSignedVAAResponse) ProtoMessage() {}
+
+func (x *GetSignedVAAResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetSignedVAAResponse.ProtoReflect.Descriptor instead.
+func (*GetSignedVAAResponse) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *GetSignedVAAResponse) GetVaaBytes() []byte {
+	if x != nil {
+		return x.VaaBytes
+	}
+	return nil
+}
+
+type GetSignedBatchVAARequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	BatchId *BatchID `protobuf:"bytes,1,opt,name=batch_id,json=batchId,proto3" json:"batch_id,omitempty"`
+}
+
+func (x *GetSignedBatchVAARequest) Reset() {
+	*x = GetSignedBatchVAARequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetSignedBatchVAARequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetSignedBatchVAARequest) ProtoMessage() {}
+
+func (x *GetSignedBatchVAARequest) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetSignedBatchVAARequest.ProtoReflect.Descriptor instead.
+func (*GetSignedBatchVAARequest) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *GetSignedBatchVAARequest) GetBatchId() *BatchID {
+	if x != nil {
+		return x.BatchId
+	}
+	return nil
+}
+
+type GetSignedBatchVAAResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	BatchVaaBytes []byte `protobuf:"bytes,1,opt,name=batch_vaa_bytes,json=batchVaaBytes,proto3" json:"batch_vaa_bytes,omitempty"`
+}
+
+func (x *GetSignedBatchVAAResponse) Reset() {
+	*x = GetSignedBatchVAAResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetSignedBatchVAAResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetSignedBatchVAAResponse) ProtoMessage() {}
+
+func (x *GetSignedBatchVAAResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetSignedBatchVAAResponse.ProtoReflect.Descriptor instead.
+func (*GetSignedBatchVAAResponse) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *GetSignedBatchVAAResponse) GetBatchVaaBytes() []byte {
+	if x != nil {
+		return x.BatchVaaBytes
+	}
+	return nil
+}
+
+type GetLastHeartbeatsRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *GetLastHeartbeatsRequest) Reset() {
+	*x = GetLastHeartbeatsRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetLastHeartbeatsRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetLastHeartbeatsRequest) ProtoMessage() {}
+
+func (x *GetLastHeartbeatsRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetLastHeartbeatsRequest.ProtoReflect.Descriptor instead.
+func (*GetLastHeartbeatsRequest) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{6}
+}
+
+type GetLastHeartbeatsResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Entries []*GetLastHeartbeatsResponse_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"`
+}
+
+func (x *GetLastHeartbeatsResponse) Reset() {
+	*x = GetLastHeartbeatsResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetLastHeartbeatsResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetLastHeartbeatsResponse) ProtoMessage() {}
+
+func (x *GetLastHeartbeatsResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetLastHeartbeatsResponse.ProtoReflect.Descriptor instead.
+func (*GetLastHeartbeatsResponse) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *GetLastHeartbeatsResponse) GetEntries() []*GetLastHeartbeatsResponse_Entry {
+	if x != nil {
+		return x.Entries
+	}
+	return nil
+}
+
+type GetCurrentGuardianSetRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *GetCurrentGuardianSetRequest) Reset() {
+	*x = GetCurrentGuardianSetRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetCurrentGuardianSetRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetCurrentGuardianSetRequest) ProtoMessage() {}
+
+func (x *GetCurrentGuardianSetRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetCurrentGuardianSetRequest.ProtoReflect.Descriptor instead.
+func (*GetCurrentGuardianSetRequest) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{8}
+}
+
+type GetCurrentGuardianSetResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	GuardianSet *GuardianSet `protobuf:"bytes,1,opt,name=guardian_set,json=guardianSet,proto3" json:"guardian_set,omitempty"`
+}
+
+func (x *GetCurrentGuardianSetResponse) Reset() {
+	*x = GetCurrentGuardianSetResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetCurrentGuardianSetResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetCurrentGuardianSetResponse) ProtoMessage() {}
+
+func (x *GetCurrentGuardianSetResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetCurrentGuardianSetResponse.ProtoReflect.Descriptor instead.
+func (*GetCurrentGuardianSetResponse) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *GetCurrentGuardianSetResponse) GetGuardianSet() *GuardianSet {
+	if x != nil {
+		return x.GuardianSet
+	}
+	return nil
+}
+
+type GuardianSet struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Guardian set index
+	Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"`
+	// List of guardian addresses as human-readable hex-encoded (leading 0x) addresses.
+	Addresses []string `protobuf:"bytes,2,rep,name=addresses,proto3" json:"addresses,omitempty"`
+}
+
+func (x *GuardianSet) Reset() {
+	*x = GuardianSet{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[10]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GuardianSet) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GuardianSet) ProtoMessage() {}
+
+func (x *GuardianSet) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[10]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GuardianSet.ProtoReflect.Descriptor instead.
+func (*GuardianSet) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *GuardianSet) GetIndex() uint32 {
+	if x != nil {
+		return x.Index
+	}
+	return 0
+}
+
+func (x *GuardianSet) GetAddresses() []string {
+	if x != nil {
+		return x.Addresses
+	}
+	return nil
+}
+
+type GovernorGetAvailableNotionalByChainRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *GovernorGetAvailableNotionalByChainRequest) Reset() {
+	*x = GovernorGetAvailableNotionalByChainRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernorGetAvailableNotionalByChainRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernorGetAvailableNotionalByChainRequest) ProtoMessage() {}
+
+func (x *GovernorGetAvailableNotionalByChainRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernorGetAvailableNotionalByChainRequest.ProtoReflect.Descriptor instead.
+func (*GovernorGetAvailableNotionalByChainRequest) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{11}
+}
+
+type GovernorGetAvailableNotionalByChainResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// There is an entry for each chain that is being governed.
+	// Chains that are not being governed are not listed, and assumed to be unlimited.
+	Entries []*GovernorGetAvailableNotionalByChainResponse_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"`
+}
+
+func (x *GovernorGetAvailableNotionalByChainResponse) Reset() {
+	*x = GovernorGetAvailableNotionalByChainResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernorGetAvailableNotionalByChainResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernorGetAvailableNotionalByChainResponse) ProtoMessage() {}
+
+func (x *GovernorGetAvailableNotionalByChainResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernorGetAvailableNotionalByChainResponse.ProtoReflect.Descriptor instead.
+func (*GovernorGetAvailableNotionalByChainResponse) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *GovernorGetAvailableNotionalByChainResponse) GetEntries() []*GovernorGetAvailableNotionalByChainResponse_Entry {
+	if x != nil {
+		return x.Entries
+	}
+	return nil
+}
+
+type GovernorGetEnqueuedVAAsRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *GovernorGetEnqueuedVAAsRequest) Reset() {
+	*x = GovernorGetEnqueuedVAAsRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernorGetEnqueuedVAAsRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernorGetEnqueuedVAAsRequest) ProtoMessage() {}
+
+func (x *GovernorGetEnqueuedVAAsRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernorGetEnqueuedVAAsRequest.ProtoReflect.Descriptor instead.
+func (*GovernorGetEnqueuedVAAsRequest) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{13}
+}
+
+type GovernorGetEnqueuedVAAsResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// There is an entry for each enqueued vaa.
+	Entries []*GovernorGetEnqueuedVAAsResponse_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"`
+}
+
+func (x *GovernorGetEnqueuedVAAsResponse) Reset() {
+	*x = GovernorGetEnqueuedVAAsResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernorGetEnqueuedVAAsResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernorGetEnqueuedVAAsResponse) ProtoMessage() {}
+
+func (x *GovernorGetEnqueuedVAAsResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernorGetEnqueuedVAAsResponse.ProtoReflect.Descriptor instead.
+func (*GovernorGetEnqueuedVAAsResponse) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *GovernorGetEnqueuedVAAsResponse) GetEntries() []*GovernorGetEnqueuedVAAsResponse_Entry {
+	if x != nil {
+		return x.Entries
+	}
+	return nil
+}
+
+type GovernorIsVAAEnqueuedRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	MessageId *MessageID `protobuf:"bytes,1,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"`
+}
+
+func (x *GovernorIsVAAEnqueuedRequest) Reset() {
+	*x = GovernorIsVAAEnqueuedRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernorIsVAAEnqueuedRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernorIsVAAEnqueuedRequest) ProtoMessage() {}
+
+func (x *GovernorIsVAAEnqueuedRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernorIsVAAEnqueuedRequest.ProtoReflect.Descriptor instead.
+func (*GovernorIsVAAEnqueuedRequest) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{15}
+}
+
+func (x *GovernorIsVAAEnqueuedRequest) GetMessageId() *MessageID {
+	if x != nil {
+		return x.MessageId
+	}
+	return nil
+}
+
+type GovernorIsVAAEnqueuedResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	IsEnqueued bool `protobuf:"varint,1,opt,name=is_enqueued,json=isEnqueued,proto3" json:"is_enqueued,omitempty"`
+}
+
+func (x *GovernorIsVAAEnqueuedResponse) Reset() {
+	*x = GovernorIsVAAEnqueuedResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[16]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernorIsVAAEnqueuedResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernorIsVAAEnqueuedResponse) ProtoMessage() {}
+
+func (x *GovernorIsVAAEnqueuedResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[16]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernorIsVAAEnqueuedResponse.ProtoReflect.Descriptor instead.
+func (*GovernorIsVAAEnqueuedResponse) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{16}
+}
+
+func (x *GovernorIsVAAEnqueuedResponse) GetIsEnqueued() bool {
+	if x != nil {
+		return x.IsEnqueued
+	}
+	return false
+}
+
+type GovernorGetTokenListRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *GovernorGetTokenListRequest) Reset() {
+	*x = GovernorGetTokenListRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[17]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernorGetTokenListRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernorGetTokenListRequest) ProtoMessage() {}
+
+func (x *GovernorGetTokenListRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[17]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernorGetTokenListRequest.ProtoReflect.Descriptor instead.
+func (*GovernorGetTokenListRequest) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{17}
+}
+
+type GovernorGetTokenListResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// There is an entry for each token that applies to the notional TVL calcuation.
+	Entries []*GovernorGetTokenListResponse_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"`
+}
+
+func (x *GovernorGetTokenListResponse) Reset() {
+	*x = GovernorGetTokenListResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[18]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernorGetTokenListResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernorGetTokenListResponse) ProtoMessage() {}
+
+func (x *GovernorGetTokenListResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[18]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernorGetTokenListResponse.ProtoReflect.Descriptor instead.
+func (*GovernorGetTokenListResponse) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{18}
+}
+
+func (x *GovernorGetTokenListResponse) GetEntries() []*GovernorGetTokenListResponse_Entry {
+	if x != nil {
+		return x.Entries
+	}
+	return nil
+}
+
+type GetLastHeartbeatsResponse_Entry struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Verified, hex-encoded (with leading 0x) guardian address. This is the guardian address
+	// which signed this heartbeat. The GuardianAddr field inside the heartbeat
+	// is NOT verified - remote nodes can put arbitrary data in it.
+	VerifiedGuardianAddr string `protobuf:"bytes,1,opt,name=verified_guardian_addr,json=verifiedGuardianAddr,proto3" json:"verified_guardian_addr,omitempty"`
+	// Base58-encoded libp2p node address that sent this heartbeat, used to
+	// distinguish between multiple nodes running for the same guardian.
+	P2PNodeAddr string `protobuf:"bytes,2,opt,name=p2p_node_addr,json=p2pNodeAddr,proto3" json:"p2p_node_addr,omitempty"`
+	// Raw heartbeat received from the network. Data is only as trusted
+	// as the guardian node that sent it - none of the fields are verified.
+	RawHeartbeat *v1.Heartbeat `protobuf:"bytes,3,opt,name=raw_heartbeat,json=rawHeartbeat,proto3" json:"raw_heartbeat,omitempty"`
+}
+
+func (x *GetLastHeartbeatsResponse_Entry) Reset() {
+	*x = GetLastHeartbeatsResponse_Entry{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[19]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetLastHeartbeatsResponse_Entry) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetLastHeartbeatsResponse_Entry) ProtoMessage() {}
+
+func (x *GetLastHeartbeatsResponse_Entry) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[19]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetLastHeartbeatsResponse_Entry.ProtoReflect.Descriptor instead.
+func (*GetLastHeartbeatsResponse_Entry) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{7, 0}
+}
+
+func (x *GetLastHeartbeatsResponse_Entry) GetVerifiedGuardianAddr() string {
+	if x != nil {
+		return x.VerifiedGuardianAddr
+	}
+	return ""
+}
+
+func (x *GetLastHeartbeatsResponse_Entry) GetP2PNodeAddr() string {
+	if x != nil {
+		return x.P2PNodeAddr
+	}
+	return ""
+}
+
+func (x *GetLastHeartbeatsResponse_Entry) GetRawHeartbeat() *v1.Heartbeat {
+	if x != nil {
+		return x.RawHeartbeat
+	}
+	return nil
+}
+
+type GovernorGetAvailableNotionalByChainResponse_Entry struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ChainId                    uint32 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
+	RemainingAvailableNotional uint64 `protobuf:"varint,2,opt,name=remaining_available_notional,json=remainingAvailableNotional,proto3" json:"remaining_available_notional,omitempty"`
+	NotionalLimit              uint64 `protobuf:"varint,3,opt,name=notional_limit,json=notionalLimit,proto3" json:"notional_limit,omitempty"`
+	BigTransactionSize         uint64 `protobuf:"varint,4,opt,name=big_transaction_size,json=bigTransactionSize,proto3" json:"big_transaction_size,omitempty"`
+}
+
+func (x *GovernorGetAvailableNotionalByChainResponse_Entry) Reset() {
+	*x = GovernorGetAvailableNotionalByChainResponse_Entry{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[20]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernorGetAvailableNotionalByChainResponse_Entry) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernorGetAvailableNotionalByChainResponse_Entry) ProtoMessage() {}
+
+func (x *GovernorGetAvailableNotionalByChainResponse_Entry) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[20]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernorGetAvailableNotionalByChainResponse_Entry.ProtoReflect.Descriptor instead.
+func (*GovernorGetAvailableNotionalByChainResponse_Entry) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{12, 0}
+}
+
+func (x *GovernorGetAvailableNotionalByChainResponse_Entry) GetChainId() uint32 {
+	if x != nil {
+		return x.ChainId
+	}
+	return 0
+}
+
+func (x *GovernorGetAvailableNotionalByChainResponse_Entry) GetRemainingAvailableNotional() uint64 {
+	if x != nil {
+		return x.RemainingAvailableNotional
+	}
+	return 0
+}
+
+func (x *GovernorGetAvailableNotionalByChainResponse_Entry) GetNotionalLimit() uint64 {
+	if x != nil {
+		return x.NotionalLimit
+	}
+	return 0
+}
+
+func (x *GovernorGetAvailableNotionalByChainResponse_Entry) GetBigTransactionSize() uint64 {
+	if x != nil {
+		return x.BigTransactionSize
+	}
+	return 0
+}
+
+type GovernorGetEnqueuedVAAsResponse_Entry struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	EmitterChain   uint32 `protobuf:"varint,1,opt,name=emitter_chain,json=emitterChain,proto3" json:"emitter_chain,omitempty"`
+	EmitterAddress string `protobuf:"bytes,2,opt,name=emitter_address,json=emitterAddress,proto3" json:"emitter_address,omitempty"` // human-readable hex-encoded (leading 0x)
+	Sequence       uint64 `protobuf:"varint,3,opt,name=sequence,proto3" json:"sequence,omitempty"`
+	ReleaseTime    uint32 `protobuf:"varint,4,opt,name=release_time,json=releaseTime,proto3" json:"release_time,omitempty"`
+	NotionalValue  uint64 `protobuf:"varint,5,opt,name=notional_value,json=notionalValue,proto3" json:"notional_value,omitempty"`
+	TxHash         string `protobuf:"bytes,6,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"`
+}
+
+func (x *GovernorGetEnqueuedVAAsResponse_Entry) Reset() {
+	*x = GovernorGetEnqueuedVAAsResponse_Entry{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[21]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernorGetEnqueuedVAAsResponse_Entry) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernorGetEnqueuedVAAsResponse_Entry) ProtoMessage() {}
+
+func (x *GovernorGetEnqueuedVAAsResponse_Entry) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[21]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernorGetEnqueuedVAAsResponse_Entry.ProtoReflect.Descriptor instead.
+func (*GovernorGetEnqueuedVAAsResponse_Entry) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{14, 0}
+}
+
+func (x *GovernorGetEnqueuedVAAsResponse_Entry) GetEmitterChain() uint32 {
+	if x != nil {
+		return x.EmitterChain
+	}
+	return 0
+}
+
+func (x *GovernorGetEnqueuedVAAsResponse_Entry) GetEmitterAddress() string {
+	if x != nil {
+		return x.EmitterAddress
+	}
+	return ""
+}
+
+func (x *GovernorGetEnqueuedVAAsResponse_Entry) GetSequence() uint64 {
+	if x != nil {
+		return x.Sequence
+	}
+	return 0
+}
+
+func (x *GovernorGetEnqueuedVAAsResponse_Entry) GetReleaseTime() uint32 {
+	if x != nil {
+		return x.ReleaseTime
+	}
+	return 0
+}
+
+func (x *GovernorGetEnqueuedVAAsResponse_Entry) GetNotionalValue() uint64 {
+	if x != nil {
+		return x.NotionalValue
+	}
+	return 0
+}
+
+func (x *GovernorGetEnqueuedVAAsResponse_Entry) GetTxHash() string {
+	if x != nil {
+		return x.TxHash
+	}
+	return ""
+}
+
+type GovernorGetTokenListResponse_Entry struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	OriginChainId uint32  `protobuf:"varint,1,opt,name=origin_chain_id,json=originChainId,proto3" json:"origin_chain_id,omitempty"`
+	OriginAddress string  `protobuf:"bytes,2,opt,name=origin_address,json=originAddress,proto3" json:"origin_address,omitempty"` // human-readable hex-encoded (leading 0x)
+	Price         float32 `protobuf:"fixed32,3,opt,name=price,proto3" json:"price,omitempty"`
+}
+
+func (x *GovernorGetTokenListResponse_Entry) Reset() {
+	*x = GovernorGetTokenListResponse_Entry{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[22]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GovernorGetTokenListResponse_Entry) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GovernorGetTokenListResponse_Entry) ProtoMessage() {}
+
+func (x *GovernorGetTokenListResponse_Entry) ProtoReflect() protoreflect.Message {
+	mi := &file_publicrpc_v1_publicrpc_proto_msgTypes[22]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GovernorGetTokenListResponse_Entry.ProtoReflect.Descriptor instead.
+func (*GovernorGetTokenListResponse_Entry) Descriptor() ([]byte, []int) {
+	return file_publicrpc_v1_publicrpc_proto_rawDescGZIP(), []int{18, 0}
+}
+
+func (x *GovernorGetTokenListResponse_Entry) GetOriginChainId() uint32 {
+	if x != nil {
+		return x.OriginChainId
+	}
+	return 0
+}
+
+func (x *GovernorGetTokenListResponse_Entry) GetOriginAddress() string {
+	if x != nil {
+		return x.OriginAddress
+	}
+	return ""
+}
+
+func (x *GovernorGetTokenListResponse_Entry) GetPrice() float32 {
+	if x != nil {
+		return x.Price
+	}
+	return 0
+}
+
+var File_publicrpc_v1_publicrpc_proto protoreflect.FileDescriptor
+
+var file_publicrpc_v1_publicrpc_proto_rawDesc = []byte{
+	0x0a, 0x1c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x70,
+	0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c,
+	0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x1a, 0x16, 0x67, 0x6f,
+	0x73, 0x73, 0x69, 0x70, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69,
+	0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x22, 0x8c, 0x01, 0x0a, 0x09, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x44,
+	0x12, 0x3a, 0x0a, 0x0d, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x69,
+	0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
+	0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x52, 0x0c,
+	0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x0f,
+	0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x41, 0x64,
+	0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+	0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+	0x65, 0x22, 0x5a, 0x0a, 0x07, 0x42, 0x61, 0x74, 0x63, 0x68, 0x49, 0x44, 0x12, 0x3a, 0x0a, 0x0d,
+	0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e,
+	0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x52, 0x0c, 0x65, 0x6d, 0x69, 0x74,
+	0x74, 0x65, 0x72, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69,
+	0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x4d, 0x0a,
+	0x13, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69,
+	0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49,
+	0x44, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x22, 0x33, 0x0a, 0x14,
+	0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x61, 0x61, 0x5f, 0x62, 0x79, 0x74, 0x65,
+	0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x76, 0x61, 0x61, 0x42, 0x79, 0x74, 0x65,
+	0x73, 0x22, 0x4c, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x61,
+	0x74, 0x63, 0x68, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a,
+	0x08, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x15, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x42,
+	0x61, 0x74, 0x63, 0x68, 0x49, 0x44, 0x52, 0x07, 0x62, 0x61, 0x74, 0x63, 0x68, 0x49, 0x64, 0x22,
+	0x43, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x74, 0x63,
+	0x68, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0f,
+	0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x76, 0x61, 0x61, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x62, 0x61, 0x74, 0x63, 0x68, 0x56, 0x61, 0x61, 0x42,
+	0x79, 0x74, 0x65, 0x73, 0x22, 0x1a, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x48,
+	0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x22, 0x83, 0x02, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x72,
+	0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47,
+	0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x2d, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47,
+	0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07,
+	0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x9c, 0x01, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72,
+	0x79, 0x12, 0x34, 0x0a, 0x16, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x67, 0x75,
+	0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x14, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x47, 0x75, 0x61, 0x72, 0x64,
+	0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x12, 0x22, 0x0a, 0x0d, 0x70, 0x32, 0x70, 0x5f, 0x6e,
+	0x6f, 0x64, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
+	0x70, 0x32, 0x70, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x12, 0x39, 0x0a, 0x0d, 0x72,
+	0x61, 0x77, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x48,
+	0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x0c, 0x72, 0x61, 0x77, 0x48, 0x65, 0x61,
+	0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x22, 0x1e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72,
+	0x72, 0x65, 0x6e, 0x74, 0x47, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5d, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72,
+	0x72, 0x65, 0x6e, 0x74, 0x47, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x67, 0x75, 0x61, 0x72, 0x64,
+	0x69, 0x61, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e,
+	0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x75, 0x61,
+	0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x0b, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69,
+	0x61, 0x6e, 0x53, 0x65, 0x74, 0x22, 0x41, 0x0a, 0x0b, 0x47, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61,
+	0x6e, 0x53, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64,
+	0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61,
+	0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x2c, 0x0a, 0x2a, 0x47, 0x6f, 0x76, 0x65,
+	0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65,
+	0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xc8, 0x02, 0x0a, 0x2b, 0x47, 0x6f, 0x76, 0x65, 0x72,
+	0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e,
+	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65,
+	0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
+	0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47,
+	0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x6f,
+	0x6e, 0x61, 0x6c, 0x42, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65,
+	0x73, 0x1a, 0xbd, 0x01, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63,
+	0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63,
+	0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x1c, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e,
+	0x69, 0x6e, 0x67, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x6f,
+	0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x72, 0x65,
+	0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65,
+	0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69,
+	0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04,
+	0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12,
+	0x30, 0x0a, 0x14, 0x62, 0x69, 0x67, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
+	0x6f, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x62,
+	0x69, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a,
+	0x65, 0x22, 0x20, 0x0a, 0x1e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74,
+	0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x22, 0xc7, 0x02, 0x0a, 0x1f, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72,
+	0x47, 0x65, 0x74, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, 0x73, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69,
+	0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69,
+	0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72,
+	0x47, 0x65, 0x74, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, 0x73, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65,
+	0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x1a, 0xd4, 0x01, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79,
+	0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x69,
+	0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72,
+	0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72,
+	0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e,
+	0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a,
+	0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04,
+	0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65,
+	0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d,
+	0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x25, 0x0a,
+	0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x56,
+	0x61, 0x6c, 0x75, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18,
+	0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0x56, 0x0a,
+	0x1c, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x49, 0x73, 0x56, 0x41, 0x41, 0x45, 0x6e,
+	0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a,
+	0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x17, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31,
+	0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x44, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x49, 0x64, 0x22, 0x40, 0x0a, 0x1d, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f,
+	0x72, 0x49, 0x73, 0x56, 0x41, 0x41, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x65, 0x6e, 0x71,
+	0x75, 0x65, 0x75, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x45,
+	0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x47, 0x6f, 0x76, 0x65, 0x72,
+	0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xd8, 0x01, 0x0a, 0x1c, 0x47, 0x6f, 0x76, 0x65, 0x72,
+	0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69,
+	0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69,
+	0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72,
+	0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72,
+	0x69, 0x65, 0x73, 0x1a, 0x6c, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x0f,
+	0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x43, 0x68, 0x61,
+	0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, 0x61,
+	0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x72,
+	0x69, 0x67, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70,
+	0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63,
+	0x65, 0x2a, 0xdb, 0x04, 0x0a, 0x07, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x12, 0x18, 0x0a,
+	0x14, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
+	0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e,
+	0x5f, 0x49, 0x44, 0x5f, 0x53, 0x4f, 0x4c, 0x41, 0x4e, 0x41, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11,
+	0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x45, 0x54, 0x48, 0x45, 0x52, 0x45, 0x55,
+	0x4d, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f,
+	0x54, 0x45, 0x52, 0x52, 0x41, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x41, 0x49, 0x4e,
+	0x5f, 0x49, 0x44, 0x5f, 0x42, 0x53, 0x43, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x48, 0x41,
+	0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x47, 0x4f, 0x4e, 0x10, 0x05, 0x12,
+	0x16, 0x0a, 0x12, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x56, 0x41, 0x4c,
+	0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x06, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e,
+	0x5f, 0x49, 0x44, 0x5f, 0x4f, 0x41, 0x53, 0x49, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x43,
+	0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x41, 0x4e, 0x44,
+	0x10, 0x08, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x41,
+	0x55, 0x52, 0x4f, 0x52, 0x41, 0x10, 0x09, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e,
+	0x5f, 0x49, 0x44, 0x5f, 0x46, 0x41, 0x4e, 0x54, 0x4f, 0x4d, 0x10, 0x0a, 0x12, 0x13, 0x0a, 0x0f,
+	0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4b, 0x41, 0x52, 0x55, 0x52, 0x41, 0x10,
+	0x0b, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x43,
+	0x41, 0x4c, 0x41, 0x10, 0x0c, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49,
+	0x44, 0x5f, 0x4b, 0x4c, 0x41, 0x59, 0x54, 0x4e, 0x10, 0x0d, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x48,
+	0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x43, 0x45, 0x4c, 0x4f, 0x10, 0x0e, 0x12, 0x11, 0x0a,
+	0x0d, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x41, 0x52, 0x10, 0x0f,
+	0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4d, 0x4f, 0x4f,
+	0x4e, 0x42, 0x45, 0x41, 0x4d, 0x10, 0x10, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x49, 0x4e,
+	0x5f, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x4f, 0x4e, 0x10, 0x11, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48,
+	0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x45, 0x52, 0x52, 0x41, 0x32, 0x10, 0x12, 0x12,
+	0x16, 0x0a, 0x12, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x49, 0x4e, 0x4a, 0x45,
+	0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x13, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x48, 0x41, 0x49, 0x4e,
+	0x5f, 0x49, 0x44, 0x5f, 0x4f, 0x53, 0x4d, 0x4f, 0x53, 0x49, 0x53, 0x10, 0x14, 0x12, 0x10, 0x0a,
+	0x0c, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x55, 0x49, 0x10, 0x15, 0x12,
+	0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x50, 0x54, 0x4f,
+	0x53, 0x10, 0x16, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f,
+	0x41, 0x52, 0x42, 0x49, 0x54, 0x52, 0x55, 0x4d, 0x10, 0x17, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48,
+	0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4d, 0x49, 0x53, 0x4d, 0x10,
+	0x18, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x47, 0x4e,
+	0x4f, 0x53, 0x49, 0x53, 0x10, 0x19, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f,
+	0x49, 0x44, 0x5f, 0x50, 0x59, 0x54, 0x48, 0x4e, 0x45, 0x54, 0x10, 0x1a, 0x12, 0x11, 0x0a, 0x0d,
+	0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x58, 0x50, 0x4c, 0x41, 0x10, 0x1c, 0x32,
+	0xf5, 0x0a, 0x0a, 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x52, 0x50, 0x43, 0x53, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x12, 0x7c, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x48,
+	0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x70, 0x75, 0x62, 0x6c,
+	0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74,
+	0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x27, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31,
+	0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61,
+	0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93,
+	0x02, 0x10, 0x12, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61,
+	0x74, 0x73, 0x12, 0xbb, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64,
+	0x56, 0x41, 0x41, 0x12, 0x21, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e,
+	0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72,
+	0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56,
+	0x41, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x82, 0xd3, 0xe4, 0x93,
+	0x02, 0x5e, 0x12, 0x5c, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x76,
+	0x61, 0x61, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x2e, 0x65,
+	0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x7d, 0x2f, 0x7b, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x2e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65,
+	0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x2e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x7d,
+	0x12, 0xac, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x61,
+	0x74, 0x63, 0x68, 0x56, 0x41, 0x41, 0x12, 0x26, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72,
+	0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42,
+	0x61, 0x74, 0x63, 0x68, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27,
+	0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
+	0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x56, 0x41, 0x41, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x40, 0x12,
+	0x3e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x74, 0x63,
+	0x68, 0x5f, 0x76, 0x61, 0x61, 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x69, 0x64, 0x2e,
+	0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x7d, 0x2f, 0x7b,
+	0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x69, 0x64, 0x2e, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x7d, 0x12,
+	0x91, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x47, 0x75,
+	0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x2a, 0x2e, 0x70, 0x75, 0x62, 0x6c,
+	0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72,
+	0x65, 0x6e, 0x74, 0x47, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70,
+	0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x47,
+	0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x2f,
+	0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x73, 0x65, 0x74, 0x2f, 0x63, 0x75, 0x72, 0x72,
+	0x65, 0x6e, 0x74, 0x12, 0xcc, 0x01, 0x0a, 0x23, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72,
+	0x47, 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x74, 0x69,
+	0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x38, 0x2e, 0x70, 0x75,
+	0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72,
+	0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e,
+	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70,
+	0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74,
+	0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61,
+	0x6c, 0x42, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f,
+	0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x2f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65,
+	0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x5f, 0x63, 0x68, 0x61,
+	0x69, 0x6e, 0x12, 0x9a, 0x01, 0x0a, 0x17, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47,
+	0x65, 0x74, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, 0x73, 0x12, 0x2c,
+	0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f,
+	0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65,
+	0x64, 0x56, 0x41, 0x41, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x70,
+	0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65,
+	0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56,
+	0x41, 0x41, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4,
+	0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f,
+	0x72, 0x2f, 0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x61, 0x73, 0x12,
+	0xe4, 0x01, 0x0a, 0x15, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x49, 0x73, 0x56, 0x41,
+	0x41, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x12, 0x2a, 0x2e, 0x70, 0x75, 0x62, 0x6c,
+	0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f,
+	0x72, 0x49, 0x73, 0x56, 0x41, 0x41, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70,
+	0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x49, 0x73, 0x56,
+	0x41, 0x41, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x72, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x6c, 0x12, 0x6a, 0x2f, 0x76, 0x31, 0x2f,
+	0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x2f, 0x69, 0x73, 0x5f, 0x76, 0x61, 0x61, 0x5f,
+	0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x5f, 0x69, 0x64, 0x2e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x68, 0x61,
+	0x69, 0x6e, 0x7d, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x2e,
+	0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d,
+	0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x2e, 0x73, 0x65, 0x71,
+	0x75, 0x65, 0x6e, 0x63, 0x65, 0x7d, 0x12, 0x8e, 0x01, 0x0a, 0x14, 0x47, 0x6f, 0x76, 0x65, 0x72,
+	0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x12,
+	0x29, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47,
+	0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c,
+	0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x75, 0x62,
+	0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e,
+	0x6f, 0x72, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17,
+	0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x2f, 0x74, 0x6f, 0x6b,
+	0x65, 0x6e, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x42, 0x47, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75,
+	0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x75, 0x73, 0x6f, 0x6e, 0x65, 0x2f,
+	0x77, 0x6f, 0x72, 0x6d, 0x68, 0x6f, 0x6c, 0x65, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b,
+	0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70,
+	0x63, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x76, 0x31,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_publicrpc_v1_publicrpc_proto_rawDescOnce sync.Once
+	file_publicrpc_v1_publicrpc_proto_rawDescData = file_publicrpc_v1_publicrpc_proto_rawDesc
+)
+
+func file_publicrpc_v1_publicrpc_proto_rawDescGZIP() []byte {
+	file_publicrpc_v1_publicrpc_proto_rawDescOnce.Do(func() {
+		file_publicrpc_v1_publicrpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_publicrpc_v1_publicrpc_proto_rawDescData)
+	})
+	return file_publicrpc_v1_publicrpc_proto_rawDescData
+}
+
+var file_publicrpc_v1_publicrpc_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_publicrpc_v1_publicrpc_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
+var file_publicrpc_v1_publicrpc_proto_goTypes = []interface{}{
+	(ChainID)(0),                                              // 0: publicrpc.v1.ChainID
+	(*MessageID)(nil),                                         // 1: publicrpc.v1.MessageID
+	(*BatchID)(nil),                                           // 2: publicrpc.v1.BatchID
+	(*GetSignedVAARequest)(nil),                               // 3: publicrpc.v1.GetSignedVAARequest
+	(*GetSignedVAAResponse)(nil),                              // 4: publicrpc.v1.GetSignedVAAResponse
+	(*GetSignedBatchVAARequest)(nil),                          // 5: publicrpc.v1.GetSignedBatchVAARequest
+	(*GetSignedBatchVAAResponse)(nil),                         // 6: publicrpc.v1.GetSignedBatchVAAResponse
+	(*GetLastHeartbeatsRequest)(nil),                          // 7: publicrpc.v1.GetLastHeartbeatsRequest
+	(*GetLastHeartbeatsResponse)(nil),                         // 8: publicrpc.v1.GetLastHeartbeatsResponse
+	(*GetCurrentGuardianSetRequest)(nil),                      // 9: publicrpc.v1.GetCurrentGuardianSetRequest
+	(*GetCurrentGuardianSetResponse)(nil),                     // 10: publicrpc.v1.GetCurrentGuardianSetResponse
+	(*GuardianSet)(nil),                                       // 11: publicrpc.v1.GuardianSet
+	(*GovernorGetAvailableNotionalByChainRequest)(nil),        // 12: publicrpc.v1.GovernorGetAvailableNotionalByChainRequest
+	(*GovernorGetAvailableNotionalByChainResponse)(nil),       // 13: publicrpc.v1.GovernorGetAvailableNotionalByChainResponse
+	(*GovernorGetEnqueuedVAAsRequest)(nil),                    // 14: publicrpc.v1.GovernorGetEnqueuedVAAsRequest
+	(*GovernorGetEnqueuedVAAsResponse)(nil),                   // 15: publicrpc.v1.GovernorGetEnqueuedVAAsResponse
+	(*GovernorIsVAAEnqueuedRequest)(nil),                      // 16: publicrpc.v1.GovernorIsVAAEnqueuedRequest
+	(*GovernorIsVAAEnqueuedResponse)(nil),                     // 17: publicrpc.v1.GovernorIsVAAEnqueuedResponse
+	(*GovernorGetTokenListRequest)(nil),                       // 18: publicrpc.v1.GovernorGetTokenListRequest
+	(*GovernorGetTokenListResponse)(nil),                      // 19: publicrpc.v1.GovernorGetTokenListResponse
+	(*GetLastHeartbeatsResponse_Entry)(nil),                   // 20: publicrpc.v1.GetLastHeartbeatsResponse.Entry
+	(*GovernorGetAvailableNotionalByChainResponse_Entry)(nil), // 21: publicrpc.v1.GovernorGetAvailableNotionalByChainResponse.Entry
+	(*GovernorGetEnqueuedVAAsResponse_Entry)(nil),             // 22: publicrpc.v1.GovernorGetEnqueuedVAAsResponse.Entry
+	(*GovernorGetTokenListResponse_Entry)(nil),                // 23: publicrpc.v1.GovernorGetTokenListResponse.Entry
+	(*v1.Heartbeat)(nil),                                      // 24: gossip.v1.Heartbeat
+}
+var file_publicrpc_v1_publicrpc_proto_depIdxs = []int32{
+	0,  // 0: publicrpc.v1.MessageID.emitter_chain:type_name -> publicrpc.v1.ChainID
+	0,  // 1: publicrpc.v1.BatchID.emitter_chain:type_name -> publicrpc.v1.ChainID
+	1,  // 2: publicrpc.v1.GetSignedVAARequest.message_id:type_name -> publicrpc.v1.MessageID
+	2,  // 3: publicrpc.v1.GetSignedBatchVAARequest.batch_id:type_name -> publicrpc.v1.BatchID
+	20, // 4: publicrpc.v1.GetLastHeartbeatsResponse.entries:type_name -> publicrpc.v1.GetLastHeartbeatsResponse.Entry
+	11, // 5: publicrpc.v1.GetCurrentGuardianSetResponse.guardian_set:type_name -> publicrpc.v1.GuardianSet
+	21, // 6: publicrpc.v1.GovernorGetAvailableNotionalByChainResponse.entries:type_name -> publicrpc.v1.GovernorGetAvailableNotionalByChainResponse.Entry
+	22, // 7: publicrpc.v1.GovernorGetEnqueuedVAAsResponse.entries:type_name -> publicrpc.v1.GovernorGetEnqueuedVAAsResponse.Entry
+	1,  // 8: publicrpc.v1.GovernorIsVAAEnqueuedRequest.message_id:type_name -> publicrpc.v1.MessageID
+	23, // 9: publicrpc.v1.GovernorGetTokenListResponse.entries:type_name -> publicrpc.v1.GovernorGetTokenListResponse.Entry
+	24, // 10: publicrpc.v1.GetLastHeartbeatsResponse.Entry.raw_heartbeat:type_name -> gossip.v1.Heartbeat
+	7,  // 11: publicrpc.v1.PublicRPCService.GetLastHeartbeats:input_type -> publicrpc.v1.GetLastHeartbeatsRequest
+	3,  // 12: publicrpc.v1.PublicRPCService.GetSignedVAA:input_type -> publicrpc.v1.GetSignedVAARequest
+	5,  // 13: publicrpc.v1.PublicRPCService.GetSignedBatchVAA:input_type -> publicrpc.v1.GetSignedBatchVAARequest
+	9,  // 14: publicrpc.v1.PublicRPCService.GetCurrentGuardianSet:input_type -> publicrpc.v1.GetCurrentGuardianSetRequest
+	12, // 15: publicrpc.v1.PublicRPCService.GovernorGetAvailableNotionalByChain:input_type -> publicrpc.v1.GovernorGetAvailableNotionalByChainRequest
+	14, // 16: publicrpc.v1.PublicRPCService.GovernorGetEnqueuedVAAs:input_type -> publicrpc.v1.GovernorGetEnqueuedVAAsRequest
+	16, // 17: publicrpc.v1.PublicRPCService.GovernorIsVAAEnqueued:input_type -> publicrpc.v1.GovernorIsVAAEnqueuedRequest
+	18, // 18: publicrpc.v1.PublicRPCService.GovernorGetTokenList:input_type -> publicrpc.v1.GovernorGetTokenListRequest
+	8,  // 19: publicrpc.v1.PublicRPCService.GetLastHeartbeats:output_type -> publicrpc.v1.GetLastHeartbeatsResponse
+	4,  // 20: publicrpc.v1.PublicRPCService.GetSignedVAA:output_type -> publicrpc.v1.GetSignedVAAResponse
+	6,  // 21: publicrpc.v1.PublicRPCService.GetSignedBatchVAA:output_type -> publicrpc.v1.GetSignedBatchVAAResponse
+	10, // 22: publicrpc.v1.PublicRPCService.GetCurrentGuardianSet:output_type -> publicrpc.v1.GetCurrentGuardianSetResponse
+	13, // 23: publicrpc.v1.PublicRPCService.GovernorGetAvailableNotionalByChain:output_type -> publicrpc.v1.GovernorGetAvailableNotionalByChainResponse
+	15, // 24: publicrpc.v1.PublicRPCService.GovernorGetEnqueuedVAAs:output_type -> publicrpc.v1.GovernorGetEnqueuedVAAsResponse
+	17, // 25: publicrpc.v1.PublicRPCService.GovernorIsVAAEnqueued:output_type -> publicrpc.v1.GovernorIsVAAEnqueuedResponse
+	19, // 26: publicrpc.v1.PublicRPCService.GovernorGetTokenList:output_type -> publicrpc.v1.GovernorGetTokenListResponse
+	19, // [19:27] is the sub-list for method output_type
+	11, // [11:19] is the sub-list for method input_type
+	11, // [11:11] is the sub-list for extension type_name
+	11, // [11:11] is the sub-list for extension extendee
+	0,  // [0:11] is the sub-list for field type_name
+}
+
+func init() { file_publicrpc_v1_publicrpc_proto_init() }
+func file_publicrpc_v1_publicrpc_proto_init() {
+	if File_publicrpc_v1_publicrpc_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_publicrpc_v1_publicrpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MessageID); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*BatchID); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetSignedVAARequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetSignedVAAResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetSignedBatchVAARequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetSignedBatchVAAResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetLastHeartbeatsRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetLastHeartbeatsResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetCurrentGuardianSetRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetCurrentGuardianSetResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GuardianSet); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernorGetAvailableNotionalByChainRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernorGetAvailableNotionalByChainResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernorGetEnqueuedVAAsRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernorGetEnqueuedVAAsResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernorIsVAAEnqueuedRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernorIsVAAEnqueuedResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernorGetTokenListRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernorGetTokenListResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetLastHeartbeatsResponse_Entry); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernorGetAvailableNotionalByChainResponse_Entry); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernorGetEnqueuedVAAsResponse_Entry); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_publicrpc_v1_publicrpc_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GovernorGetTokenListResponse_Entry); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_publicrpc_v1_publicrpc_proto_rawDesc,
+			NumEnums:      1,
+			NumMessages:   23,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_publicrpc_v1_publicrpc_proto_goTypes,
+		DependencyIndexes: file_publicrpc_v1_publicrpc_proto_depIdxs,
+		EnumInfos:         file_publicrpc_v1_publicrpc_proto_enumTypes,
+		MessageInfos:      file_publicrpc_v1_publicrpc_proto_msgTypes,
+	}.Build()
+	File_publicrpc_v1_publicrpc_proto = out.File
+	file_publicrpc_v1_publicrpc_proto_rawDesc = nil
+	file_publicrpc_v1_publicrpc_proto_goTypes = nil
+	file_publicrpc_v1_publicrpc_proto_depIdxs = nil
+}

+ 910 - 0
node/pkg/proto/publicrpc/v1/publicrpc.pb.gw.go

@@ -0,0 +1,910 @@
+// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
+// source: publicrpc/v1/publicrpc.proto
+
+/*
+Package publicrpcv1 is a reverse proxy.
+
+It translates gRPC into RESTful JSON APIs.
+*/
+package publicrpcv1
+
+import (
+	"context"
+	"io"
+	"net/http"
+
+	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+	"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/grpclog"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/grpc/status"
+	"google.golang.org/protobuf/proto"
+)
+
+// Suppress "imported and not used" errors
+var _ codes.Code
+var _ io.Reader
+var _ status.Status
+var _ = runtime.String
+var _ = utilities.NewDoubleArray
+var _ = metadata.Join
+
+func request_PublicRPCService_GetLastHeartbeats_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetLastHeartbeatsRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.GetLastHeartbeats(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_PublicRPCService_GetLastHeartbeats_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetLastHeartbeatsRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.GetLastHeartbeats(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_PublicRPCService_GetSignedVAA_0 = &utilities.DoubleArray{Encoding: map[string]int{"message_id": 0, "emitter_chain": 1, "emitter_address": 2, "sequence": 3}, Base: []int{1, 1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 2, 2, 2, 3, 4, 5}}
+)
+
+func request_PublicRPCService_GetSignedVAA_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetSignedVAARequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		e   int32
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["message_id.emitter_chain"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_chain")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_chain", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_chain", err)
+	}
+
+	e, err = runtime.Enum(val, ChainID_value)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "message_id.emitter_chain", err)
+	}
+
+	protoReq.MessageId.EmitterChain = ChainID(e)
+
+	val, ok = pathParams["message_id.emitter_address"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_address")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_address", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_address", err)
+	}
+
+	val, ok = pathParams["message_id.sequence"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.sequence")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.sequence", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.sequence", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GetSignedVAA_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.GetSignedVAA(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_PublicRPCService_GetSignedVAA_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetSignedVAARequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		e   int32
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["message_id.emitter_chain"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_chain")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_chain", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_chain", err)
+	}
+
+	e, err = runtime.Enum(val, ChainID_value)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "message_id.emitter_chain", err)
+	}
+
+	protoReq.MessageId.EmitterChain = ChainID(e)
+
+	val, ok = pathParams["message_id.emitter_address"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_address")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_address", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_address", err)
+	}
+
+	val, ok = pathParams["message_id.sequence"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.sequence")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.sequence", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.sequence", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GetSignedVAA_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.GetSignedVAA(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_PublicRPCService_GetSignedBatchVAA_0 = &utilities.DoubleArray{Encoding: map[string]int{"batch_id": 0, "emitter_chain": 1, "tx_id": 2}, Base: []int{1, 1, 1, 2, 0, 0}, Check: []int{0, 1, 2, 2, 3, 4}}
+)
+
+func request_PublicRPCService_GetSignedBatchVAA_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetSignedBatchVAARequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		e   int32
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["batch_id.emitter_chain"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "batch_id.emitter_chain")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "batch_id.emitter_chain", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "batch_id.emitter_chain", err)
+	}
+
+	e, err = runtime.Enum(val, ChainID_value)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "batch_id.emitter_chain", err)
+	}
+
+	protoReq.BatchId.EmitterChain = ChainID(e)
+
+	val, ok = pathParams["batch_id.tx_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "batch_id.tx_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "batch_id.tx_id", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "batch_id.tx_id", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GetSignedBatchVAA_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.GetSignedBatchVAA(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_PublicRPCService_GetSignedBatchVAA_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetSignedBatchVAARequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		e   int32
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["batch_id.emitter_chain"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "batch_id.emitter_chain")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "batch_id.emitter_chain", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "batch_id.emitter_chain", err)
+	}
+
+	e, err = runtime.Enum(val, ChainID_value)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "batch_id.emitter_chain", err)
+	}
+
+	protoReq.BatchId.EmitterChain = ChainID(e)
+
+	val, ok = pathParams["batch_id.tx_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "batch_id.tx_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "batch_id.tx_id", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "batch_id.tx_id", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GetSignedBatchVAA_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.GetSignedBatchVAA(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_PublicRPCService_GetCurrentGuardianSet_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetCurrentGuardianSetRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.GetCurrentGuardianSet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_PublicRPCService_GetCurrentGuardianSet_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetCurrentGuardianSetRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.GetCurrentGuardianSet(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_PublicRPCService_GovernorGetAvailableNotionalByChain_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GovernorGetAvailableNotionalByChainRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.GovernorGetAvailableNotionalByChain(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_PublicRPCService_GovernorGetAvailableNotionalByChain_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GovernorGetAvailableNotionalByChainRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.GovernorGetAvailableNotionalByChain(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_PublicRPCService_GovernorGetEnqueuedVAAs_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GovernorGetEnqueuedVAAsRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.GovernorGetEnqueuedVAAs(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_PublicRPCService_GovernorGetEnqueuedVAAs_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GovernorGetEnqueuedVAAsRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.GovernorGetEnqueuedVAAs(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_PublicRPCService_GovernorIsVAAEnqueued_0 = &utilities.DoubleArray{Encoding: map[string]int{"message_id": 0, "emitter_chain": 1, "emitter_address": 2, "sequence": 3}, Base: []int{1, 1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 2, 2, 2, 3, 4, 5}}
+)
+
+func request_PublicRPCService_GovernorIsVAAEnqueued_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GovernorIsVAAEnqueuedRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		e   int32
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["message_id.emitter_chain"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_chain")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_chain", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_chain", err)
+	}
+
+	e, err = runtime.Enum(val, ChainID_value)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "message_id.emitter_chain", err)
+	}
+
+	protoReq.MessageId.EmitterChain = ChainID(e)
+
+	val, ok = pathParams["message_id.emitter_address"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_address")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_address", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_address", err)
+	}
+
+	val, ok = pathParams["message_id.sequence"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.sequence")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.sequence", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.sequence", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GovernorIsVAAEnqueued_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.GovernorIsVAAEnqueued(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_PublicRPCService_GovernorIsVAAEnqueued_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GovernorIsVAAEnqueuedRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		e   int32
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["message_id.emitter_chain"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_chain")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_chain", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_chain", err)
+	}
+
+	e, err = runtime.Enum(val, ChainID_value)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "message_id.emitter_chain", err)
+	}
+
+	protoReq.MessageId.EmitterChain = ChainID(e)
+
+	val, ok = pathParams["message_id.emitter_address"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_address")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_address", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_address", err)
+	}
+
+	val, ok = pathParams["message_id.sequence"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.sequence")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "message_id.sequence", val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.sequence", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GovernorIsVAAEnqueued_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.GovernorIsVAAEnqueued(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_PublicRPCService_GovernorGetTokenList_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GovernorGetTokenListRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.GovernorGetTokenList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_PublicRPCService_GovernorGetTokenList_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GovernorGetTokenListRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.GovernorGetTokenList(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+// RegisterPublicRPCServiceHandlerServer registers the http handlers for service PublicRPCService to "mux".
+// UnaryRPC     :call PublicRPCServiceServer directly.
+// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
+// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterPublicRPCServiceHandlerFromEndpoint instead.
+func RegisterPublicRPCServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server PublicRPCServiceServer) error {
+
+	mux.Handle("GET", pattern_PublicRPCService_GetLastHeartbeats_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetLastHeartbeats", runtime.WithHTTPPathPattern("/v1/heartbeats"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_PublicRPCService_GetLastHeartbeats_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GetLastHeartbeats_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GetSignedVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetSignedVAA", runtime.WithHTTPPathPattern("/v1/signed_vaa/{message_id.emitter_chain}/{message_id.emitter_address}/{message_id.sequence}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_PublicRPCService_GetSignedVAA_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GetSignedVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GetSignedBatchVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetSignedBatchVAA", runtime.WithHTTPPathPattern("/v1/signed_batch_vaa/{batch_id.emitter_chain}/{batch_id.tx_id}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_PublicRPCService_GetSignedBatchVAA_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GetSignedBatchVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GetCurrentGuardianSet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetCurrentGuardianSet", runtime.WithHTTPPathPattern("/v1/guardianset/current"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_PublicRPCService_GetCurrentGuardianSet_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GetCurrentGuardianSet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GovernorGetAvailableNotionalByChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetAvailableNotionalByChain", runtime.WithHTTPPathPattern("/v1/governor/available_notional_by_chain"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_PublicRPCService_GovernorGetAvailableNotionalByChain_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GovernorGetAvailableNotionalByChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GovernorGetEnqueuedVAAs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetEnqueuedVAAs", runtime.WithHTTPPathPattern("/v1/governor/enqueued_vaas"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_PublicRPCService_GovernorGetEnqueuedVAAs_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GovernorGetEnqueuedVAAs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GovernorIsVAAEnqueued_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorIsVAAEnqueued", runtime.WithHTTPPathPattern("/v1/governor/is_vaa_enqueued/{message_id.emitter_chain}/{message_id.emitter_address}/{message_id.sequence}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_PublicRPCService_GovernorIsVAAEnqueued_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GovernorIsVAAEnqueued_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GovernorGetTokenList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetTokenList", runtime.WithHTTPPathPattern("/v1/governor/token_list"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_PublicRPCService_GovernorGetTokenList_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GovernorGetTokenList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	return nil
+}
+
+// RegisterPublicRPCServiceHandlerFromEndpoint is same as RegisterPublicRPCServiceHandler but
+// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
+func RegisterPublicRPCServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
+	conn, err := grpc.Dial(endpoint, opts...)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		if err != nil {
+			if cerr := conn.Close(); cerr != nil {
+				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+			}
+			return
+		}
+		go func() {
+			<-ctx.Done()
+			if cerr := conn.Close(); cerr != nil {
+				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+			}
+		}()
+	}()
+
+	return RegisterPublicRPCServiceHandler(ctx, mux, conn)
+}
+
+// RegisterPublicRPCServiceHandler registers the http handlers for service PublicRPCService to "mux".
+// The handlers forward requests to the grpc endpoint over "conn".
+func RegisterPublicRPCServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+	return RegisterPublicRPCServiceHandlerClient(ctx, mux, NewPublicRPCServiceClient(conn))
+}
+
+// RegisterPublicRPCServiceHandlerClient registers the http handlers for service PublicRPCService
+// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "PublicRPCServiceClient".
+// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "PublicRPCServiceClient"
+// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
+// "PublicRPCServiceClient" to call the correct interceptors.
+func RegisterPublicRPCServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client PublicRPCServiceClient) error {
+
+	mux.Handle("GET", pattern_PublicRPCService_GetLastHeartbeats_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetLastHeartbeats", runtime.WithHTTPPathPattern("/v1/heartbeats"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_PublicRPCService_GetLastHeartbeats_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GetLastHeartbeats_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GetSignedVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetSignedVAA", runtime.WithHTTPPathPattern("/v1/signed_vaa/{message_id.emitter_chain}/{message_id.emitter_address}/{message_id.sequence}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_PublicRPCService_GetSignedVAA_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GetSignedVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GetSignedBatchVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetSignedBatchVAA", runtime.WithHTTPPathPattern("/v1/signed_batch_vaa/{batch_id.emitter_chain}/{batch_id.tx_id}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_PublicRPCService_GetSignedBatchVAA_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GetSignedBatchVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GetCurrentGuardianSet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetCurrentGuardianSet", runtime.WithHTTPPathPattern("/v1/guardianset/current"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_PublicRPCService_GetCurrentGuardianSet_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GetCurrentGuardianSet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GovernorGetAvailableNotionalByChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetAvailableNotionalByChain", runtime.WithHTTPPathPattern("/v1/governor/available_notional_by_chain"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_PublicRPCService_GovernorGetAvailableNotionalByChain_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GovernorGetAvailableNotionalByChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GovernorGetEnqueuedVAAs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetEnqueuedVAAs", runtime.WithHTTPPathPattern("/v1/governor/enqueued_vaas"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_PublicRPCService_GovernorGetEnqueuedVAAs_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GovernorGetEnqueuedVAAs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GovernorIsVAAEnqueued_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorIsVAAEnqueued", runtime.WithHTTPPathPattern("/v1/governor/is_vaa_enqueued/{message_id.emitter_chain}/{message_id.emitter_address}/{message_id.sequence}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_PublicRPCService_GovernorIsVAAEnqueued_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GovernorIsVAAEnqueued_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_PublicRPCService_GovernorGetTokenList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetTokenList", runtime.WithHTTPPathPattern("/v1/governor/token_list"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_PublicRPCService_GovernorGetTokenList_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_PublicRPCService_GovernorGetTokenList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	return nil
+}
+
+var (
+	pattern_PublicRPCService_GetLastHeartbeats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "heartbeats"}, ""))
+
+	pattern_PublicRPCService_GetSignedVAA_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "signed_vaa", "message_id.emitter_chain", "message_id.emitter_address", "message_id.sequence"}, ""))
+
+	pattern_PublicRPCService_GetSignedBatchVAA_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "signed_batch_vaa", "batch_id.emitter_chain", "batch_id.tx_id"}, ""))
+
+	pattern_PublicRPCService_GetCurrentGuardianSet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "guardianset", "current"}, ""))
+
+	pattern_PublicRPCService_GovernorGetAvailableNotionalByChain_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "governor", "available_notional_by_chain"}, ""))
+
+	pattern_PublicRPCService_GovernorGetEnqueuedVAAs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "governor", "enqueued_vaas"}, ""))
+
+	pattern_PublicRPCService_GovernorIsVAAEnqueued_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"v1", "governor", "is_vaa_enqueued", "message_id.emitter_chain", "message_id.emitter_address", "message_id.sequence"}, ""))
+
+	pattern_PublicRPCService_GovernorGetTokenList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "governor", "token_list"}, ""))
+)
+
+var (
+	forward_PublicRPCService_GetLastHeartbeats_0 = runtime.ForwardResponseMessage
+
+	forward_PublicRPCService_GetSignedVAA_0 = runtime.ForwardResponseMessage
+
+	forward_PublicRPCService_GetSignedBatchVAA_0 = runtime.ForwardResponseMessage
+
+	forward_PublicRPCService_GetCurrentGuardianSet_0 = runtime.ForwardResponseMessage
+
+	forward_PublicRPCService_GovernorGetAvailableNotionalByChain_0 = runtime.ForwardResponseMessage
+
+	forward_PublicRPCService_GovernorGetEnqueuedVAAs_0 = runtime.ForwardResponseMessage
+
+	forward_PublicRPCService_GovernorIsVAAEnqueued_0 = runtime.ForwardResponseMessage
+
+	forward_PublicRPCService_GovernorGetTokenList_0 = runtime.ForwardResponseMessage
+)

+ 359 - 0
node/pkg/proto/publicrpc/v1/publicrpc_grpc.pb.go

@@ -0,0 +1,359 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package publicrpcv1
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+// PublicRPCServiceClient is the client API for PublicRPCService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type PublicRPCServiceClient interface {
+	// GetLastHeartbeats returns the last heartbeat received for each guardian node in the
+	// node's active guardian set. Heartbeats received by nodes not in the guardian set are ignored.
+	// The heartbeat value is null if no heartbeat has yet been received.
+	GetLastHeartbeats(ctx context.Context, in *GetLastHeartbeatsRequest, opts ...grpc.CallOption) (*GetLastHeartbeatsResponse, error)
+	GetSignedVAA(ctx context.Context, in *GetSignedVAARequest, opts ...grpc.CallOption) (*GetSignedVAAResponse, error)
+	GetSignedBatchVAA(ctx context.Context, in *GetSignedBatchVAARequest, opts ...grpc.CallOption) (*GetSignedBatchVAAResponse, error)
+	GetCurrentGuardianSet(ctx context.Context, in *GetCurrentGuardianSetRequest, opts ...grpc.CallOption) (*GetCurrentGuardianSetResponse, error)
+	GovernorGetAvailableNotionalByChain(ctx context.Context, in *GovernorGetAvailableNotionalByChainRequest, opts ...grpc.CallOption) (*GovernorGetAvailableNotionalByChainResponse, error)
+	GovernorGetEnqueuedVAAs(ctx context.Context, in *GovernorGetEnqueuedVAAsRequest, opts ...grpc.CallOption) (*GovernorGetEnqueuedVAAsResponse, error)
+	GovernorIsVAAEnqueued(ctx context.Context, in *GovernorIsVAAEnqueuedRequest, opts ...grpc.CallOption) (*GovernorIsVAAEnqueuedResponse, error)
+	GovernorGetTokenList(ctx context.Context, in *GovernorGetTokenListRequest, opts ...grpc.CallOption) (*GovernorGetTokenListResponse, error)
+}
+
+type publicRPCServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewPublicRPCServiceClient(cc grpc.ClientConnInterface) PublicRPCServiceClient {
+	return &publicRPCServiceClient{cc}
+}
+
+func (c *publicRPCServiceClient) GetLastHeartbeats(ctx context.Context, in *GetLastHeartbeatsRequest, opts ...grpc.CallOption) (*GetLastHeartbeatsResponse, error) {
+	out := new(GetLastHeartbeatsResponse)
+	err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GetLastHeartbeats", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *publicRPCServiceClient) GetSignedVAA(ctx context.Context, in *GetSignedVAARequest, opts ...grpc.CallOption) (*GetSignedVAAResponse, error) {
+	out := new(GetSignedVAAResponse)
+	err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GetSignedVAA", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *publicRPCServiceClient) GetSignedBatchVAA(ctx context.Context, in *GetSignedBatchVAARequest, opts ...grpc.CallOption) (*GetSignedBatchVAAResponse, error) {
+	out := new(GetSignedBatchVAAResponse)
+	err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GetSignedBatchVAA", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *publicRPCServiceClient) GetCurrentGuardianSet(ctx context.Context, in *GetCurrentGuardianSetRequest, opts ...grpc.CallOption) (*GetCurrentGuardianSetResponse, error) {
+	out := new(GetCurrentGuardianSetResponse)
+	err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GetCurrentGuardianSet", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *publicRPCServiceClient) GovernorGetAvailableNotionalByChain(ctx context.Context, in *GovernorGetAvailableNotionalByChainRequest, opts ...grpc.CallOption) (*GovernorGetAvailableNotionalByChainResponse, error) {
+	out := new(GovernorGetAvailableNotionalByChainResponse)
+	err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GovernorGetAvailableNotionalByChain", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *publicRPCServiceClient) GovernorGetEnqueuedVAAs(ctx context.Context, in *GovernorGetEnqueuedVAAsRequest, opts ...grpc.CallOption) (*GovernorGetEnqueuedVAAsResponse, error) {
+	out := new(GovernorGetEnqueuedVAAsResponse)
+	err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GovernorGetEnqueuedVAAs", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *publicRPCServiceClient) GovernorIsVAAEnqueued(ctx context.Context, in *GovernorIsVAAEnqueuedRequest, opts ...grpc.CallOption) (*GovernorIsVAAEnqueuedResponse, error) {
+	out := new(GovernorIsVAAEnqueuedResponse)
+	err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GovernorIsVAAEnqueued", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *publicRPCServiceClient) GovernorGetTokenList(ctx context.Context, in *GovernorGetTokenListRequest, opts ...grpc.CallOption) (*GovernorGetTokenListResponse, error) {
+	out := new(GovernorGetTokenListResponse)
+	err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GovernorGetTokenList", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// PublicRPCServiceServer is the server API for PublicRPCService service.
+// All implementations must embed UnimplementedPublicRPCServiceServer
+// for forward compatibility
+type PublicRPCServiceServer interface {
+	// GetLastHeartbeats returns the last heartbeat received for each guardian node in the
+	// node's active guardian set. Heartbeats received by nodes not in the guardian set are ignored.
+	// The heartbeat value is null if no heartbeat has yet been received.
+	GetLastHeartbeats(context.Context, *GetLastHeartbeatsRequest) (*GetLastHeartbeatsResponse, error)
+	GetSignedVAA(context.Context, *GetSignedVAARequest) (*GetSignedVAAResponse, error)
+	GetSignedBatchVAA(context.Context, *GetSignedBatchVAARequest) (*GetSignedBatchVAAResponse, error)
+	GetCurrentGuardianSet(context.Context, *GetCurrentGuardianSetRequest) (*GetCurrentGuardianSetResponse, error)
+	GovernorGetAvailableNotionalByChain(context.Context, *GovernorGetAvailableNotionalByChainRequest) (*GovernorGetAvailableNotionalByChainResponse, error)
+	GovernorGetEnqueuedVAAs(context.Context, *GovernorGetEnqueuedVAAsRequest) (*GovernorGetEnqueuedVAAsResponse, error)
+	GovernorIsVAAEnqueued(context.Context, *GovernorIsVAAEnqueuedRequest) (*GovernorIsVAAEnqueuedResponse, error)
+	GovernorGetTokenList(context.Context, *GovernorGetTokenListRequest) (*GovernorGetTokenListResponse, error)
+	mustEmbedUnimplementedPublicRPCServiceServer()
+}
+
+// UnimplementedPublicRPCServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedPublicRPCServiceServer struct {
+}
+
+func (UnimplementedPublicRPCServiceServer) GetLastHeartbeats(context.Context, *GetLastHeartbeatsRequest) (*GetLastHeartbeatsResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetLastHeartbeats not implemented")
+}
+func (UnimplementedPublicRPCServiceServer) GetSignedVAA(context.Context, *GetSignedVAARequest) (*GetSignedVAAResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetSignedVAA not implemented")
+}
+func (UnimplementedPublicRPCServiceServer) GetSignedBatchVAA(context.Context, *GetSignedBatchVAARequest) (*GetSignedBatchVAAResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetSignedBatchVAA not implemented")
+}
+func (UnimplementedPublicRPCServiceServer) GetCurrentGuardianSet(context.Context, *GetCurrentGuardianSetRequest) (*GetCurrentGuardianSetResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetCurrentGuardianSet not implemented")
+}
+func (UnimplementedPublicRPCServiceServer) GovernorGetAvailableNotionalByChain(context.Context, *GovernorGetAvailableNotionalByChainRequest) (*GovernorGetAvailableNotionalByChainResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GovernorGetAvailableNotionalByChain not implemented")
+}
+func (UnimplementedPublicRPCServiceServer) GovernorGetEnqueuedVAAs(context.Context, *GovernorGetEnqueuedVAAsRequest) (*GovernorGetEnqueuedVAAsResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GovernorGetEnqueuedVAAs not implemented")
+}
+func (UnimplementedPublicRPCServiceServer) GovernorIsVAAEnqueued(context.Context, *GovernorIsVAAEnqueuedRequest) (*GovernorIsVAAEnqueuedResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GovernorIsVAAEnqueued not implemented")
+}
+func (UnimplementedPublicRPCServiceServer) GovernorGetTokenList(context.Context, *GovernorGetTokenListRequest) (*GovernorGetTokenListResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GovernorGetTokenList not implemented")
+}
+func (UnimplementedPublicRPCServiceServer) mustEmbedUnimplementedPublicRPCServiceServer() {}
+
+// UnsafePublicRPCServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to PublicRPCServiceServer will
+// result in compilation errors.
+type UnsafePublicRPCServiceServer interface {
+	mustEmbedUnimplementedPublicRPCServiceServer()
+}
+
+func RegisterPublicRPCServiceServer(s grpc.ServiceRegistrar, srv PublicRPCServiceServer) {
+	s.RegisterService(&PublicRPCService_ServiceDesc, srv)
+}
+
+func _PublicRPCService_GetLastHeartbeats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetLastHeartbeatsRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(PublicRPCServiceServer).GetLastHeartbeats(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/publicrpc.v1.PublicRPCService/GetLastHeartbeats",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(PublicRPCServiceServer).GetLastHeartbeats(ctx, req.(*GetLastHeartbeatsRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _PublicRPCService_GetSignedVAA_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetSignedVAARequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(PublicRPCServiceServer).GetSignedVAA(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/publicrpc.v1.PublicRPCService/GetSignedVAA",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(PublicRPCServiceServer).GetSignedVAA(ctx, req.(*GetSignedVAARequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _PublicRPCService_GetSignedBatchVAA_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetSignedBatchVAARequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(PublicRPCServiceServer).GetSignedBatchVAA(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/publicrpc.v1.PublicRPCService/GetSignedBatchVAA",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(PublicRPCServiceServer).GetSignedBatchVAA(ctx, req.(*GetSignedBatchVAARequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _PublicRPCService_GetCurrentGuardianSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetCurrentGuardianSetRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(PublicRPCServiceServer).GetCurrentGuardianSet(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/publicrpc.v1.PublicRPCService/GetCurrentGuardianSet",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(PublicRPCServiceServer).GetCurrentGuardianSet(ctx, req.(*GetCurrentGuardianSetRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _PublicRPCService_GovernorGetAvailableNotionalByChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GovernorGetAvailableNotionalByChainRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(PublicRPCServiceServer).GovernorGetAvailableNotionalByChain(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/publicrpc.v1.PublicRPCService/GovernorGetAvailableNotionalByChain",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(PublicRPCServiceServer).GovernorGetAvailableNotionalByChain(ctx, req.(*GovernorGetAvailableNotionalByChainRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _PublicRPCService_GovernorGetEnqueuedVAAs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GovernorGetEnqueuedVAAsRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(PublicRPCServiceServer).GovernorGetEnqueuedVAAs(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/publicrpc.v1.PublicRPCService/GovernorGetEnqueuedVAAs",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(PublicRPCServiceServer).GovernorGetEnqueuedVAAs(ctx, req.(*GovernorGetEnqueuedVAAsRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _PublicRPCService_GovernorIsVAAEnqueued_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GovernorIsVAAEnqueuedRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(PublicRPCServiceServer).GovernorIsVAAEnqueued(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/publicrpc.v1.PublicRPCService/GovernorIsVAAEnqueued",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(PublicRPCServiceServer).GovernorIsVAAEnqueued(ctx, req.(*GovernorIsVAAEnqueuedRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _PublicRPCService_GovernorGetTokenList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GovernorGetTokenListRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(PublicRPCServiceServer).GovernorGetTokenList(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/publicrpc.v1.PublicRPCService/GovernorGetTokenList",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(PublicRPCServiceServer).GovernorGetTokenList(ctx, req.(*GovernorGetTokenListRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// PublicRPCService_ServiceDesc is the grpc.ServiceDesc for PublicRPCService service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var PublicRPCService_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "publicrpc.v1.PublicRPCService",
+	HandlerType: (*PublicRPCServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "GetLastHeartbeats",
+			Handler:    _PublicRPCService_GetLastHeartbeats_Handler,
+		},
+		{
+			MethodName: "GetSignedVAA",
+			Handler:    _PublicRPCService_GetSignedVAA_Handler,
+		},
+		{
+			MethodName: "GetSignedBatchVAA",
+			Handler:    _PublicRPCService_GetSignedBatchVAA_Handler,
+		},
+		{
+			MethodName: "GetCurrentGuardianSet",
+			Handler:    _PublicRPCService_GetCurrentGuardianSet_Handler,
+		},
+		{
+			MethodName: "GovernorGetAvailableNotionalByChain",
+			Handler:    _PublicRPCService_GovernorGetAvailableNotionalByChain_Handler,
+		},
+		{
+			MethodName: "GovernorGetEnqueuedVAAs",
+			Handler:    _PublicRPCService_GovernorGetEnqueuedVAAs_Handler,
+		},
+		{
+			MethodName: "GovernorIsVAAEnqueued",
+			Handler:    _PublicRPCService_GovernorIsVAAEnqueued_Handler,
+		},
+		{
+			MethodName: "GovernorGetTokenList",
+			Handler:    _PublicRPCService_GovernorGetTokenList_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "publicrpc/v1/publicrpc.proto",
+}

+ 400 - 0
node/pkg/proto/spy/v1/spy.pb.go

@@ -0,0 +1,400 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.27.1
+// 	protoc        (unknown)
+// source: spy/v1/spy.proto
+
+package spyv1
+
+import (
+	v1 "github.com/certusone/wormhole/node/pkg/proto/publicrpc/v1"
+	_ "google.golang.org/genproto/googleapis/api/annotations"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// A MessageFilter represents an exact match for an emitter.
+type EmitterFilter struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Source chain
+	ChainId v1.ChainID `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3,enum=publicrpc.v1.ChainID" json:"chain_id,omitempty"`
+	// Hex-encoded (without leading 0x) emitter address.
+	EmitterAddress string `protobuf:"bytes,2,opt,name=emitter_address,json=emitterAddress,proto3" json:"emitter_address,omitempty"`
+}
+
+func (x *EmitterFilter) Reset() {
+	*x = EmitterFilter{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_spy_v1_spy_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *EmitterFilter) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*EmitterFilter) ProtoMessage() {}
+
+func (x *EmitterFilter) ProtoReflect() protoreflect.Message {
+	mi := &file_spy_v1_spy_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use EmitterFilter.ProtoReflect.Descriptor instead.
+func (*EmitterFilter) Descriptor() ([]byte, []int) {
+	return file_spy_v1_spy_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *EmitterFilter) GetChainId() v1.ChainID {
+	if x != nil {
+		return x.ChainId
+	}
+	return v1.ChainID(0)
+}
+
+func (x *EmitterFilter) GetEmitterAddress() string {
+	if x != nil {
+		return x.EmitterAddress
+	}
+	return ""
+}
+
+type FilterEntry struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to Filter:
+	//	*FilterEntry_EmitterFilter
+	Filter isFilterEntry_Filter `protobuf_oneof:"filter"`
+}
+
+func (x *FilterEntry) Reset() {
+	*x = FilterEntry{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_spy_v1_spy_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FilterEntry) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FilterEntry) ProtoMessage() {}
+
+func (x *FilterEntry) ProtoReflect() protoreflect.Message {
+	mi := &file_spy_v1_spy_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FilterEntry.ProtoReflect.Descriptor instead.
+func (*FilterEntry) Descriptor() ([]byte, []int) {
+	return file_spy_v1_spy_proto_rawDescGZIP(), []int{1}
+}
+
+func (m *FilterEntry) GetFilter() isFilterEntry_Filter {
+	if m != nil {
+		return m.Filter
+	}
+	return nil
+}
+
+func (x *FilterEntry) GetEmitterFilter() *EmitterFilter {
+	if x, ok := x.GetFilter().(*FilterEntry_EmitterFilter); ok {
+		return x.EmitterFilter
+	}
+	return nil
+}
+
+type isFilterEntry_Filter interface {
+	isFilterEntry_Filter()
+}
+
+type FilterEntry_EmitterFilter struct {
+	EmitterFilter *EmitterFilter `protobuf:"bytes,1,opt,name=emitter_filter,json=emitterFilter,proto3,oneof"`
+}
+
+func (*FilterEntry_EmitterFilter) isFilterEntry_Filter() {}
+
+type SubscribeSignedVAARequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// List of filters to apply to the stream (OR).
+	// If empty, all messages are streamed.
+	Filters []*FilterEntry `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"`
+}
+
+func (x *SubscribeSignedVAARequest) Reset() {
+	*x = SubscribeSignedVAARequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_spy_v1_spy_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SubscribeSignedVAARequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SubscribeSignedVAARequest) ProtoMessage() {}
+
+func (x *SubscribeSignedVAARequest) ProtoReflect() protoreflect.Message {
+	mi := &file_spy_v1_spy_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SubscribeSignedVAARequest.ProtoReflect.Descriptor instead.
+func (*SubscribeSignedVAARequest) Descriptor() ([]byte, []int) {
+	return file_spy_v1_spy_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *SubscribeSignedVAARequest) GetFilters() []*FilterEntry {
+	if x != nil {
+		return x.Filters
+	}
+	return nil
+}
+
+type SubscribeSignedVAAResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Raw VAA bytes
+	VaaBytes []byte `protobuf:"bytes,1,opt,name=vaa_bytes,json=vaaBytes,proto3" json:"vaa_bytes,omitempty"`
+}
+
+func (x *SubscribeSignedVAAResponse) Reset() {
+	*x = SubscribeSignedVAAResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_spy_v1_spy_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SubscribeSignedVAAResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SubscribeSignedVAAResponse) ProtoMessage() {}
+
+func (x *SubscribeSignedVAAResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_spy_v1_spy_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SubscribeSignedVAAResponse.ProtoReflect.Descriptor instead.
+func (*SubscribeSignedVAAResponse) Descriptor() ([]byte, []int) {
+	return file_spy_v1_spy_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *SubscribeSignedVAAResponse) GetVaaBytes() []byte {
+	if x != nil {
+		return x.VaaBytes
+	}
+	return nil
+}
+
+var File_spy_v1_spy_proto protoreflect.FileDescriptor
+
+var file_spy_v1_spy_proto_rawDesc = []byte{
+	0x0a, 0x10, 0x73, 0x70, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x70, 0x79, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x12, 0x06, 0x73, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67,
+	0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
+	0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6a, 0x0a, 0x0d, 0x45, 0x6d, 0x69, 0x74, 0x74, 0x65,
+	0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e,
+	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x70, 0x75, 0x62, 0x6c,
+	0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44,
+	0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6d, 0x69,
+	0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65,
+	0x73, 0x73, 0x22, 0x57, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72,
+	0x79, 0x12, 0x3e, 0x0a, 0x0e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x6c,
+	0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x70, 0x79, 0x2e,
+	0x76, 0x31, 0x2e, 0x45, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72,
+	0x48, 0x00, 0x52, 0x0d, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65,
+	0x72, 0x42, 0x08, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x4a, 0x0a, 0x19, 0x53,
+	0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41,
+	0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74,
+	0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x70, 0x79, 0x2e,
+	0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07,
+	0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x39, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x73, 0x63,
+	0x72, 0x69, 0x62, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x61, 0x61, 0x5f, 0x62, 0x79, 0x74,
+	0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x76, 0x61, 0x61, 0x42, 0x79, 0x74,
+	0x65, 0x73, 0x32, 0x94, 0x01, 0x0a, 0x0d, 0x53, 0x70, 0x79, 0x52, 0x50, 0x43, 0x53, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
+	0x62, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x12, 0x21, 0x2e, 0x73, 0x70,
+	0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x69,
+	0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22,
+	0x2e, 0x73, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62,
+	0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x3a,
+	0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64,
+	0x5f, 0x76, 0x61, 0x61, 0x3a, 0x01, 0x2a, 0x30, 0x01, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74,
+	0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x75, 0x73, 0x6f, 0x6e,
+	0x65, 0x2f, 0x77, 0x6f, 0x72, 0x6d, 0x68, 0x6f, 0x6c, 0x65, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f,
+	0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x70, 0x79, 0x2f, 0x76, 0x31,
+	0x3b, 0x73, 0x70, 0x79, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_spy_v1_spy_proto_rawDescOnce sync.Once
+	file_spy_v1_spy_proto_rawDescData = file_spy_v1_spy_proto_rawDesc
+)
+
+func file_spy_v1_spy_proto_rawDescGZIP() []byte {
+	file_spy_v1_spy_proto_rawDescOnce.Do(func() {
+		file_spy_v1_spy_proto_rawDescData = protoimpl.X.CompressGZIP(file_spy_v1_spy_proto_rawDescData)
+	})
+	return file_spy_v1_spy_proto_rawDescData
+}
+
+var file_spy_v1_spy_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_spy_v1_spy_proto_goTypes = []interface{}{
+	(*EmitterFilter)(nil),              // 0: spy.v1.EmitterFilter
+	(*FilterEntry)(nil),                // 1: spy.v1.FilterEntry
+	(*SubscribeSignedVAARequest)(nil),  // 2: spy.v1.SubscribeSignedVAARequest
+	(*SubscribeSignedVAAResponse)(nil), // 3: spy.v1.SubscribeSignedVAAResponse
+	(v1.ChainID)(0),                    // 4: publicrpc.v1.ChainID
+}
+var file_spy_v1_spy_proto_depIdxs = []int32{
+	4, // 0: spy.v1.EmitterFilter.chain_id:type_name -> publicrpc.v1.ChainID
+	0, // 1: spy.v1.FilterEntry.emitter_filter:type_name -> spy.v1.EmitterFilter
+	1, // 2: spy.v1.SubscribeSignedVAARequest.filters:type_name -> spy.v1.FilterEntry
+	2, // 3: spy.v1.SpyRPCService.SubscribeSignedVAA:input_type -> spy.v1.SubscribeSignedVAARequest
+	3, // 4: spy.v1.SpyRPCService.SubscribeSignedVAA:output_type -> spy.v1.SubscribeSignedVAAResponse
+	4, // [4:5] is the sub-list for method output_type
+	3, // [3:4] is the sub-list for method input_type
+	3, // [3:3] is the sub-list for extension type_name
+	3, // [3:3] is the sub-list for extension extendee
+	0, // [0:3] is the sub-list for field type_name
+}
+
+func init() { file_spy_v1_spy_proto_init() }
+func file_spy_v1_spy_proto_init() {
+	if File_spy_v1_spy_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_spy_v1_spy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*EmitterFilter); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_spy_v1_spy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FilterEntry); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_spy_v1_spy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SubscribeSignedVAARequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_spy_v1_spy_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SubscribeSignedVAAResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_spy_v1_spy_proto_msgTypes[1].OneofWrappers = []interface{}{
+		(*FilterEntry_EmitterFilter)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_spy_v1_spy_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   4,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_spy_v1_spy_proto_goTypes,
+		DependencyIndexes: file_spy_v1_spy_proto_depIdxs,
+		MessageInfos:      file_spy_v1_spy_proto_msgTypes,
+	}.Build()
+	File_spy_v1_spy_proto = out.File
+	file_spy_v1_spy_proto_rawDesc = nil
+	file_spy_v1_spy_proto_goTypes = nil
+	file_spy_v1_spy_proto_depIdxs = nil
+}

+ 142 - 0
node/pkg/proto/spy/v1/spy.pb.gw.go

@@ -0,0 +1,142 @@
+// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
+// source: spy/v1/spy.proto
+
+/*
+Package spyv1 is a reverse proxy.
+
+It translates gRPC into RESTful JSON APIs.
+*/
+package spyv1
+
+import (
+	"context"
+	"io"
+	"net/http"
+
+	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+	"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/grpclog"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/grpc/status"
+	"google.golang.org/protobuf/proto"
+)
+
+// Suppress "imported and not used" errors
+var _ codes.Code
+var _ io.Reader
+var _ status.Status
+var _ = runtime.String
+var _ = utilities.NewDoubleArray
+var _ = metadata.Join
+
+func request_SpyRPCService_SubscribeSignedVAA_0(ctx context.Context, marshaler runtime.Marshaler, client SpyRPCServiceClient, req *http.Request, pathParams map[string]string) (SpyRPCService_SubscribeSignedVAAClient, runtime.ServerMetadata, error) {
+	var protoReq SubscribeSignedVAARequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	stream, err := client.SubscribeSignedVAA(ctx, &protoReq)
+	if err != nil {
+		return nil, metadata, err
+	}
+	header, err := stream.Header()
+	if err != nil {
+		return nil, metadata, err
+	}
+	metadata.HeaderMD = header
+	return stream, metadata, nil
+
+}
+
+// RegisterSpyRPCServiceHandlerServer registers the http handlers for service SpyRPCService to "mux".
+// UnaryRPC     :call SpyRPCServiceServer directly.
+// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
+// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterSpyRPCServiceHandlerFromEndpoint instead.
+func RegisterSpyRPCServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server SpyRPCServiceServer) error {
+
+	mux.Handle("POST", pattern_SpyRPCService_SubscribeSignedVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		err := status.Error(codes.Unimplemented, "streaming calls are not yet supported in the in-process transport")
+		_, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+		return
+	})
+
+	return nil
+}
+
+// RegisterSpyRPCServiceHandlerFromEndpoint is same as RegisterSpyRPCServiceHandler but
+// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
+func RegisterSpyRPCServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
+	conn, err := grpc.Dial(endpoint, opts...)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		if err != nil {
+			if cerr := conn.Close(); cerr != nil {
+				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+			}
+			return
+		}
+		go func() {
+			<-ctx.Done()
+			if cerr := conn.Close(); cerr != nil {
+				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+			}
+		}()
+	}()
+
+	return RegisterSpyRPCServiceHandler(ctx, mux, conn)
+}
+
+// RegisterSpyRPCServiceHandler registers the http handlers for service SpyRPCService to "mux".
+// The handlers forward requests to the grpc endpoint over "conn".
+func RegisterSpyRPCServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+	return RegisterSpyRPCServiceHandlerClient(ctx, mux, NewSpyRPCServiceClient(conn))
+}
+
+// RegisterSpyRPCServiceHandlerClient registers the http handlers for service SpyRPCService
+// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "SpyRPCServiceClient".
+// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "SpyRPCServiceClient"
+// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
+// "SpyRPCServiceClient" to call the correct interceptors.
+func RegisterSpyRPCServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client SpyRPCServiceClient) error {
+
+	mux.Handle("POST", pattern_SpyRPCService_SubscribeSignedVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/spy.v1.SpyRPCService/SubscribeSignedVAA", runtime.WithHTTPPathPattern("/v1:subscribe_signed_vaa"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_SpyRPCService_SubscribeSignedVAA_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_SpyRPCService_SubscribeSignedVAA_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
+
+	})
+
+	return nil
+}
+
+var (
+	pattern_SpyRPCService_SubscribeSignedVAA_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"v1"}, "subscribe_signed_vaa"))
+)
+
+var (
+	forward_SpyRPCService_SubscribeSignedVAA_0 = runtime.ForwardResponseStream
+)

+ 130 - 0
node/pkg/proto/spy/v1/spy_grpc.pb.go

@@ -0,0 +1,130 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package spyv1
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+// SpyRPCServiceClient is the client API for SpyRPCService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type SpyRPCServiceClient interface {
+	// SubscribeSignedVAA returns a stream of signed VAA messages received on the network.
+	SubscribeSignedVAA(ctx context.Context, in *SubscribeSignedVAARequest, opts ...grpc.CallOption) (SpyRPCService_SubscribeSignedVAAClient, error)
+}
+
+type spyRPCServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewSpyRPCServiceClient(cc grpc.ClientConnInterface) SpyRPCServiceClient {
+	return &spyRPCServiceClient{cc}
+}
+
+func (c *spyRPCServiceClient) SubscribeSignedVAA(ctx context.Context, in *SubscribeSignedVAARequest, opts ...grpc.CallOption) (SpyRPCService_SubscribeSignedVAAClient, error) {
+	stream, err := c.cc.NewStream(ctx, &SpyRPCService_ServiceDesc.Streams[0], "/spy.v1.SpyRPCService/SubscribeSignedVAA", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &spyRPCServiceSubscribeSignedVAAClient{stream}
+	if err := x.ClientStream.SendMsg(in); err != nil {
+		return nil, err
+	}
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+type SpyRPCService_SubscribeSignedVAAClient interface {
+	Recv() (*SubscribeSignedVAAResponse, error)
+	grpc.ClientStream
+}
+
+type spyRPCServiceSubscribeSignedVAAClient struct {
+	grpc.ClientStream
+}
+
+func (x *spyRPCServiceSubscribeSignedVAAClient) Recv() (*SubscribeSignedVAAResponse, error) {
+	m := new(SubscribeSignedVAAResponse)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// SpyRPCServiceServer is the server API for SpyRPCService service.
+// All implementations must embed UnimplementedSpyRPCServiceServer
+// for forward compatibility
+type SpyRPCServiceServer interface {
+	// SubscribeSignedVAA returns a stream of signed VAA messages received on the network.
+	SubscribeSignedVAA(*SubscribeSignedVAARequest, SpyRPCService_SubscribeSignedVAAServer) error
+	mustEmbedUnimplementedSpyRPCServiceServer()
+}
+
+// UnimplementedSpyRPCServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedSpyRPCServiceServer struct {
+}
+
+func (UnimplementedSpyRPCServiceServer) SubscribeSignedVAA(*SubscribeSignedVAARequest, SpyRPCService_SubscribeSignedVAAServer) error {
+	return status.Errorf(codes.Unimplemented, "method SubscribeSignedVAA not implemented")
+}
+func (UnimplementedSpyRPCServiceServer) mustEmbedUnimplementedSpyRPCServiceServer() {}
+
+// UnsafeSpyRPCServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to SpyRPCServiceServer will
+// result in compilation errors.
+type UnsafeSpyRPCServiceServer interface {
+	mustEmbedUnimplementedSpyRPCServiceServer()
+}
+
+func RegisterSpyRPCServiceServer(s grpc.ServiceRegistrar, srv SpyRPCServiceServer) {
+	s.RegisterService(&SpyRPCService_ServiceDesc, srv)
+}
+
+func _SpyRPCService_SubscribeSignedVAA_Handler(srv interface{}, stream grpc.ServerStream) error {
+	m := new(SubscribeSignedVAARequest)
+	if err := stream.RecvMsg(m); err != nil {
+		return err
+	}
+	return srv.(SpyRPCServiceServer).SubscribeSignedVAA(m, &spyRPCServiceSubscribeSignedVAAServer{stream})
+}
+
+type SpyRPCService_SubscribeSignedVAAServer interface {
+	Send(*SubscribeSignedVAAResponse) error
+	grpc.ServerStream
+}
+
+type spyRPCServiceSubscribeSignedVAAServer struct {
+	grpc.ServerStream
+}
+
+func (x *spyRPCServiceSubscribeSignedVAAServer) Send(m *SubscribeSignedVAAResponse) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+// SpyRPCService_ServiceDesc is the grpc.ServiceDesc for SpyRPCService service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var SpyRPCService_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "spy.v1.SpyRPCService",
+	HandlerType: (*SpyRPCServiceServer)(nil),
+	Methods:     []grpc.MethodDesc{},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "SubscribeSignedVAA",
+			Handler:       _SpyRPCService_SubscribeSignedVAA_Handler,
+			ServerStreams: true,
+		},
+	},
+	Metadata: "spy/v1/spy.proto",
+}