syntax = "proto3"; option go_package = "github.com/luxfi/netrunner;rpcpb"; package rpcpb; import "google/api/annotations.proto"; service PingService { rpc Ping(PingRequest) returns (PingResponse) { option (google.api.http) = { post: "/v1/ping" body: "*" }; } } message PingRequest {} message PingResponse { int32 pid = 1; } service ControlService { rpc RPCVersion(RPCVersionRequest) returns (RPCVersionResponse) { option (google.api.http) = { post: "/v1/control/rpcversion" body: "*" }; } rpc Start(StartRequest) returns (StartResponse) { option (google.api.http) = { post: "/v1/control/start" body: "*" }; } rpc CreateBlockchains(CreateBlockchainsRequest) returns (CreateBlockchainsResponse) { option (google.api.http) = { post: "/v1/control/createblockchains" body: "*" }; } rpc TransformElasticChains(TransformElasticChainsRequest) returns (TransformElasticChainsResponse) { option (google.api.http) = { post: "/v1/control/transformelasticchains" body: "*" }; } rpc AddPermissionlessValidator(AddPermissionlessValidatorRequest) returns (AddPermissionlessValidatorResponse) { option (google.api.http) = { post: "/v1/control/addpermissionlessvalidator" body: "*" }; } rpc RemoveChainValidator(RemoveChainValidatorRequest) returns (RemoveChainValidatorResponse) { option (google.api.http) = { post: "/v1/control/removechainvalidator" body: "*" }; } rpc CreateChains(CreateChainsRequest) returns (CreateChainsResponse) { option (google.api.http) = { post: "/v1/control/createchains" body: "*" }; } rpc Health(HealthRequest) returns (HealthResponse) { option (google.api.http) = { post: "/v1/control/health" body: "*" }; } rpc URIs(URIsRequest) returns (URIsResponse) { option (google.api.http) = { post: "/v1/control/uris" body: "*" }; } rpc WaitForHealthy(WaitForHealthyRequest) returns (WaitForHealthyResponse) { option (google.api.http) = { post: "/v1/control/waitforhealthy" body: "*" }; } rpc Status(StatusRequest) returns (StatusResponse) { option (google.api.http) = { post: "/v1/control/status" body: "*" }; } rpc StreamStatus(StreamStatusRequest) returns (stream StreamStatusResponse) { option (google.api.http) = { post: "/v1/control/streamstatus" body: "*" }; } rpc RemoveNode(RemoveNodeRequest) returns (RemoveNodeResponse) { option (google.api.http) = { post: "/v1/control/removenode" body: "*" }; } rpc AddNode(AddNodeRequest) returns (AddNodeResponse) { option (google.api.http) = { post: "/v1/control/addnode" body: "*" }; } rpc RestartNode(RestartNodeRequest) returns (RestartNodeResponse) { option (google.api.http) = { post: "/v1/control/restartnode" body: "*" }; } rpc PauseNode(PauseNodeRequest) returns (PauseNodeResponse) { option (google.api.http) = { post: "/v1/control/pausenode" body: "*" }; } rpc ResumeNode(ResumeNodeRequest) returns (ResumeNodeResponse) { option (google.api.http) = { post: "/v1/control/resumenode" body: "*" }; } rpc Stop(StopRequest) returns (StopResponse) { option (google.api.http) = { post: "/v1/control/stop" body: "*" }; } rpc AttachPeer(AttachPeerRequest) returns (AttachPeerResponse) { option (google.api.http) = { post: "/v1/control/attachpeer" body: "*" }; } rpc SendOutboundMessage(SendOutboundMessageRequest) returns (SendOutboundMessageResponse) { option (google.api.http) = { post: "/v1/control/sendoutboundmessage" body: "*" }; } rpc SaveSnapshot(SaveSnapshotRequest) returns (SaveSnapshotResponse) { option (google.api.http) = { post: "/v1/control/savesnapshot" body: "*" }; } // SaveHotSnapshot saves a snapshot without stopping the network // Uses Copy-on-Write on APFS (macOS) for instant snapshots rpc SaveHotSnapshot(SaveSnapshotRequest) returns (SaveSnapshotResponse) { option (google.api.http) = { post: "/v1/control/savehotsnapshot" body: "*" }; } rpc LoadSnapshot(LoadSnapshotRequest) returns (LoadSnapshotResponse) { option (google.api.http) = { post: "/v1/control/loadsnapshot" body: "*" }; } rpc RemoveSnapshot(RemoveSnapshotRequest) returns (RemoveSnapshotResponse) { option (google.api.http) = { post: "/v1/control/removesnapshot" body: "*" }; } rpc GetSnapshotNames(GetSnapshotNamesRequest) returns (GetSnapshotNamesResponse) { option (google.api.http) = { post: "/v1/control/getsnapshotnames" body: "*" }; } } message ChainParticipants { repeated string node_names = 1; } message ClusterInfo { repeated string node_names = 1; map node_infos = 2; int32 pid = 3; string root_data_dir = 4; bool healthy = 5; // Maps from the node ID to its attached peer infos. map attached_peer_infos = 6; // Set to "true" once custom blockchains are ready. bool custom_chains_healthy = 7; // The map of blockchain IDs in "ids.ID" format to its blockchain information. map custom_chains = 8; map chains = 9; } message ChainInfo { // If Chain is an Elastic Chain bool is_elastic = 1; // TXID for the elastic chain transform string elastic_chain_id = 2; // node validators of chain ChainParticipants chain_participants = 3; } message CustomChainInfo { // Blockchain name given to the create blockchain TX // Currently used to keep a record of the VM name, // which is not saved anywhere and can't be recovered from VM ID string chain_name = 1; // VM ID in "ids.ID" format. string vm_id = 2; // Create chain transaction ID -- P-Chain chain ID. // The chain ID must be whitelisted by the lux node. string pchain_id = 3; // Create blockchain transaction ID -- blockchain ID> // The blockchain ID is used for RPC endpoints. string blockchain_id = 4; } message NodeInfo { string name = 1; string exec_path = 2; string uri = 3; string id = 4; string log_dir = 5; string db_dir = 6; string plugin_dir = 7; string whitelisted_chains = 8; bytes config = 9; bool paused = 10; } message AttachedPeerInfo { string id = 1; } message ListOfAttachedPeerInfo { repeated AttachedPeerInfo peers = 1; } message StartRequest { // Network identifier - name or ID // Supported values: "mainnet" (1), "testnet" (2), "devnet" (3), "custom" (1337) // or any custom network name string network_name = 1; // Node consensus engine type // Supported values: "luxd", "avalanchego", "geth", "op-node", "custom" string node_type = 2; string exec_path = 4; optional uint32 num_nodes = 5; optional string whitelisted_chains = 6; optional string global_node_config = 7; // Used for both database and log files. optional string root_data_dir = 8; // Plugin dir from which to load all custom VM executables. string plugin_dir = 9; // The list of: // - custom chain's VM name // - genesis file path // - (optional) chain id to use. // - chain config file path // - network upgrade file path // // chain id must be always nil when using StartRequest, as the network is empty and has no preloaded // chain ids available. // // The matching file with the name in "ids.ID" format must exist. // e.g., ids.ToID(hashing.ComputeHash256("chainevm")).String() // e.g., chain-cli create VMID chainevm // // If this field is set to none (by default), the node/network-runner // does not install the custom chain and does not create the chain, // even if the VM binary exists on the local plugins directory. repeated BlockchainSpec blockchain_specs = 10; map custom_node_configs = 11; // Map of chain name to config file contents. // If specified, will create a file "chainname/config.json" with // the contents provided here. map chain_configs = 12; // Map of chain name to upgrade file contents. // If specified, will create a file "chainname/upgrade.json" with // the contents provided here. map upgrade_configs = 13; // reassign default/custom ports if they are already taken optional bool reassign_ports_if_used = 14; // use dynamic ports instead of default ones optional bool dynamic_ports = 15; // Map of chain id to chain config file contents. // If specified, will create a file "chainid.json" under chains config dir with // the contents provided here. map chain_config_files = 16; } message RPCVersionRequest {} message RPCVersionResponse { uint32 version = 1; } message StartResponse { ClusterInfo cluster_info = 1; repeated string chain_ids = 2; } message ChainSpec { // if empty, assumes all nodes should be participants repeated string participants = 1; // either file path or file contents string chain_config_file = 2; } message ElasticChainSpec { string chain_id = 1; string asset_name = 2; string asset_symbol = 3; uint64 initial_supply = 4; uint64 max_supply = 5; uint64 min_consumption_rate = 6; uint64 max_consumption_rate = 7; uint64 min_validator_stake = 8; uint64 max_validator_stake = 9; uint64 min_stake_duration = 10; uint64 max_stake_duration = 11; uint32 min_delegation_fee = 12; uint64 min_delegator_stake = 13; uint32 max_validator_weight_factor = 14; uint32 uptime_requirement = 15; } message TransformElasticChainsRequest { repeated ElasticChainSpec elastic_chain_spec = 1; } message TransformElasticChainsResponse { ClusterInfo cluster_info = 1; repeated string tx_ids = 2; repeated string asset_ids = 3; } message PermissionlessValidatorSpec { string chain_id = 1; string node_name = 2; uint64 staked_token_amount = 3; string asset_id = 4; string start_time = 5; uint64 stake_duration = 6; } message AddPermissionlessValidatorRequest { repeated PermissionlessValidatorSpec validator_spec = 1; } message AddPermissionlessValidatorResponse { ClusterInfo cluster_info = 1; } message RemoveChainValidatorSpec { string chain_id = 1; repeated string node_names = 2; } message RemoveChainValidatorRequest { repeated RemoveChainValidatorSpec validator_spec = 1; } message RemoveChainValidatorResponse { ClusterInfo cluster_info = 1; } message BlockchainSpec { string vm_name = 1; // either file path or file contents string genesis = 2; // either a chain_id is given for a previously created chain, // or a chain specification is given for a new chain generation optional string chain_id = 3; optional ChainSpec chain_spec = 4; // General chain config, either file path or file contents string chain_config = 5; // either file path or file contents string network_upgrade = 6; string blockchain_alias = 7; // Per node chain config, either file path or file contents string per_node_chain_config = 8; } message CreateBlockchainsRequest { // The list of: // - custom chain's VM name // - genesis file path // - (optional) chain id to use. // - chain config file path // - network upgrade file path // - chain config file path // - chain config file path for specific nodes // // The matching file with the name in "ids.ID" format must exist. // e.g., ids.ToID(hashing.ComputeHash256("chainevm")).String() // e.g., chain-cli create VMID chainevm // // If this field is set to none (by default), the node/network-runner // will return error repeated BlockchainSpec blockchain_specs = 1; } message CreateBlockchainsResponse { ClusterInfo cluster_info = 1; repeated string chain_ids = 2; } message CreateChainsRequest { repeated ChainSpec chain_specs = 1; } message CreateChainsResponse { ClusterInfo cluster_info = 1; repeated string chain_ids = 2; } message HealthRequest { // Network name to check health for // If empty, checks overall server health optional string network_name = 1; } message HealthResponse { ClusterInfo cluster_info = 1; // Network-specific health information optional NetworkHealth network_health = 2; } message NetworkHealth { string network_name = 1; uint32 network_id = 2; bool healthy = 3; repeated string healthy_nodes = 4; repeated string unhealthy_nodes = 5; } message URIsRequest {} message URIsResponse { repeated string uris = 1; } message WaitForHealthyRequest { // Network name to wait for // If empty, waits for any network to be healthy optional string network_name = 1; } message WaitForHealthyResponse { ClusterInfo cluster_info = 1; } message StatusRequest { // Network name to get status for // If empty, returns overall server status optional string network_name = 1; } message StatusResponse { ClusterInfo cluster_info = 1; // Network-specific status information optional NetworkStatus network_status = 2; } message NetworkStatus { string network_name = 1; uint32 network_id = 2; string status = 3; // "running", "stopped", "starting", "error" uint32 num_nodes = 4; repeated rpcpb.NodeInfo nodes = 5; repeated rpcpb.ChainInfo chains = 6; } message StreamStatusRequest { int64 push_interval = 1; } message StreamStatusResponse { ClusterInfo cluster_info = 1; } message RestartNodeRequest { // Must be a valid node name. string name = 1; // Optional fields are set to the previous values if empty. optional string exec_path = 2; optional string whitelisted_chains = 3; // Map of chain name to config file contents. // If specified, will create a file "chainname/config.json" with // the contents provided here. map chain_configs = 4; // Map of chain name to config file contents. // If specified, will create a file "chainname/upgrade.json" with // the contents provided here. map upgrade_configs = 5; // Map of chain id to chain config file contents. // If specified, will create a file "chainid.json" under chains config dir with // the contents provided here. map chain_config_files = 6; // Plugin dir from which to load all custom VM executables. string plugin_dir = 7; } message RestartNodeResponse { ClusterInfo cluster_info = 1; } message RemoveNodeRequest { string name = 1; } message RemoveNodeResponse { ClusterInfo cluster_info = 1; } message PauseNodeRequest { string name = 1; } message PauseNodeResponse { ClusterInfo cluster_info = 1; } message ResumeNodeRequest { string name = 1; } message ResumeNodeResponse { ClusterInfo cluster_info = 1; } message AddNodeRequest { string name = 1; string exec_path = 2; optional string node_config = 3; // Map of chain name to config file contents. // If specified, will create a file "chainname/config.json" with // the contents provided here. map chain_configs = 4; // Map of chain name to config file contents. // If specified, will create a file "chainname/upgrade.json" with // the contents provided here. map upgrade_configs = 5; // Map of chain id to chain config file contents. // If specified, will create a file "chainid.json" under chains config dir with // the contents provided here. map chain_config_files = 6; // Plugin dir from which to load all custom VM executables. string plugin_dir = 7; } message AddNodeResponse { ClusterInfo cluster_info = 1; } message StopRequest {} message StopResponse { ClusterInfo cluster_info = 1; } message AttachPeerRequest { string node_name = 1; } message AttachPeerResponse { ClusterInfo cluster_info = 1; AttachedPeerInfo attached_peer_info = 2; } message SendOutboundMessageRequest { string node_name = 1; string peer_id = 2; uint32 op = 3; bytes bytes = 4; } message SendOutboundMessageResponse { bool sent = 1; } message SaveSnapshotRequest { string network_name = 1; string snapshot_name = 2; } message SaveSnapshotResponse { string snapshot_path = 1; } message LoadSnapshotRequest { string network_name = 1; string snapshot_name = 2; optional string exec_path = 3; string plugin_dir = 4; optional string root_data_dir = 5; map chain_configs = 6; map upgrade_configs = 7; optional string global_node_config = 8; optional bool reassign_ports_if_used = 9; map chain_config_files = 10; } message LoadSnapshotResponse { ClusterInfo cluster_info = 1; } message RemoveSnapshotRequest { string network_name = 1; string snapshot_name = 2; } message RemoveSnapshotResponse { } message GetSnapshotNamesRequest { string network_name = 1; } message GetSnapshotNamesResponse { repeated string snapshot_names = 1; }