syntax = "proto3";
package greenlight;

// The node service represents your node running on greenlight's
// infrastructure. You can use the exposed RPC methods to interact
// with your node. The URI used to connect to the node depends on
// where the node is being scheduled and is returned by the
// `Scheduler.Schedule()` RPC call.
//
// Notice that in order to connect to the node the caller must use the
// node-specific mTLS keypair returned by `Scheduler.Register()` or
// `Scheduler.Recover()`. In particular the anonymous mTLS keypair is
// rejected by the node.
//
// Deprecated methods are being replaced by the standardized and
// automatically managed cln-grpc protocol you can find in
// `node.proto`
service Node {
	// Stream incoming payments
	//
	// Currently includes off-chain payments received matching an
	// invoice or spontaneus paymens through keysend.
	rpc StreamIncoming(StreamIncomingFilter) returns (stream IncomingPayment) {}

	// Stream the logs as they are produced by the node
	//
	// Mainly intended for debugging clients by tailing the log as
	// they are written on the node. The logs start streaming from
	// the first beginning, in order to allow inspection of events
	// after an error occurred, That also means that the logs can
	// be rather large, and should not be streamed onto
	// resource-constrained devices.
	rpc StreamLog(StreamLogRequest) returns (stream LogEntry) {}

	// Listen for incoming `custommsg` messages from peers.
	//
	// The messages are forwarded as they come in, and will not be
	// replayed if the stream is interrupted.
	rpc StreamCustommsg(StreamCustommsgRequest) returns (stream Custommsg) {}

	//////////////////////////////// HSM Messages ////////////////////////
	//
	// The following messages are related to communicating HSM
	// requests back and forth. Chances are you won't need to
	// interact with these at all, unless you want to embed the
	// hsmd into your client. We recommend using a standalone hsmd
	// such as hagrid, keeper of keys, to get started.
	//
	// Stream requests from the node to any key device that can
	// respond to them.
	rpc StreamHsmRequests(Empty) returns (stream HsmRequest) {}

	rpc RespondHsmRequest(HsmResponse) returns (Empty) {}

	rpc Configure(GlConfig) returns (Empty) {}

	rpc TrampolinePay(TrampolinePayRequest) returns (TrampolinePayResponse) {}
}

message HsmRequestContext {
	bytes node_id = 1;
	uint64 dbid = 2;
	uint64 capabilities = 3;
}

message HsmResponse {
	uint32 request_id = 1;
	bytes raw = 2;

	// A list of updated key-value-version tuples that is to be
	// merged into the state tracked by the plugin.
	repeated SignerStateEntry signer_state = 5;

	// If the signer reported an error, and did therefore not include
	// `raw`, this is the stringified error, so we can print it in the
	// logs. This should help us collate policy errors with the changes
	// proposed by CLN
	string error = 6;
}

message HsmRequest {
	uint32 request_id = 1;
	HsmRequestContext context = 2;
	bytes raw = 3;

	// A list of key-value-version tuples that the signer should
	// use to update its internal state.
	repeated SignerStateEntry signer_state = 4;

	// Currently active requests that are used to justify changes
	// in state.
	repeated PendingRequest requests = 5;
}

message Empty {}
service Hsm {
	rpc Request(HsmRequest) returns (HsmResponse) {}
	rpc Ping(Empty) returns (Empty) {}
}

message Amount {
	oneof unit {
		uint64 millisatoshi = 1;
		uint64 satoshi = 2;
		uint64 bitcoin = 3;
		bool all = 4;
		bool any = 5;
	}
}

// Options to stream_incoming to specify what to stream.
message StreamIncomingFilter {
}

message TlvField {
	uint64 type = 1;
	// length is implied since the value field carries its own
	// length here.
	bytes value = 2;
}

message OffChainPayment {
	string label = 1;
	bytes preimage = 2;
	Amount amount = 3;
	repeated TlvField extratlvs = 4;
	bytes payment_hash = 5;
	string bolt11 = 6;
}

message IncomingPayment {
	oneof details {
		OffChainPayment offchain = 1;
	}
}

message StreamLogRequest {};
message LogEntry {
	string line = 1;
}

message SignerStateEntry {
	uint64 version = 1;
	string key = 2;
	bytes value = 3;
}

// This represents a grpc request that is currently pending, along
// with the pubkey of the client issuing the request and a matching
// signature. This allows the signer to verify that the state changes
// implied in a signature request correspond to authentic grpc
// commands, and were not injected somewhere along the way.
message PendingRequest {
	bytes request = 1;
	string uri = 2;
	bytes signature = 3;
	bytes pubkey = 4;
	uint64 timestamp = 5;
	bytes rune = 6;
}


// The `NodeConfig` is used to pass startup parameters to the
// node. The `gl-plugin` will look for a file in its directory to load
// these values from. Please refer to the individual fields to learn
// what they do.
message NodeConfig {
	// In order to start without a signer attached we need to
	// stash a couple of canned messages that we'd otherwise ask
	// from the signer. These are just request-response tuples
	// that we use to match and reply against incoming requests.
	repeated StartupMessage startupmsgs = 1;
}


// The `GlConfig` is used to pass greenlight-specific startup parameters
// to the node. The `gl-plugin` will look for a serialized config object in 
// the node's datastore to load these values from. Please refer to the 
// individual fields to learn what they do.
message GlConfig {
	string close_to_addr = 1;
}

// A message that we know will be requested by `lightningd` at
// startup, and that we stash a response to on the scheduler. This
// allows the scheduler to start a node without requiring the signer
// to connect first. Messages are stored in full, including type
// prefix, but without the length prefix.
message StartupMessage {
  bytes request = 1;
  bytes response = 2;
}

message StreamCustommsgRequest {}

message Custommsg {
  bytes peer_id = 1;
  bytes payload = 2;
}

message TrampolinePayRequest {
	string bolt11 = 1;
	bytes trampoline_node_id = 2;
	uint64 amount_msat = 3;
	string label = 4;
	float maxfeepercent	= 5;
	uint32 maxdelay = 6;
	string description = 7;
}

message TrampolinePayResponse {
	enum PayStatus {
		COMPLETE = 0;
		FAILED = 2;
	}
	bytes payment_preimage = 1;
	bytes payment_hash = 2;
	double created_at = 3;
	uint32 parts = 4;
	uint64 amount_msat = 5;
	uint64 amount_sent_msat = 6;
	bytes destination = 7;
}
