syntax = "proto3";

package invoicesrpc;

import "lightning.proto";

option go_package = "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc";

/*
 * Comments in this file will be directly parsed into the API
 * Documentation as descriptions of the associated method, message, or field.
 * These descriptions should go right above the definition of the object, and
 * can be in either block or // comment format.
 *
 * An RPC method can be matched to an lncli command by placing a line in the
 * beginning of the description in exactly the following format:
 * lncli: `methodname`
 *
 * Failure to specify the exact name of the command will cause documentation
 * generation to fail.
 *
 * More information on how exactly the gRPC documentation is generated from
 * this proto file can be found here:
 * https://github.com/lightninglabs/lightning-api
 */

// Invoices is a service that can be used to create, accept, settle and cancel
// invoices.
service Invoices {
    /*
    SubscribeSingleInvoice returns a uni-directional stream (server -> client)
    to notify the client of state transitions of the specified invoice.
    Initially the current invoice state is always sent out.
    */
    rpc SubscribeSingleInvoice (SubscribeSingleInvoiceRequest)
        returns (stream lnrpc.Invoice);

    /* lncli: `cancelinvoice`
    CancelInvoice cancels a currently open invoice. If the invoice is already
    canceled, this call will succeed. If the invoice is already settled, it will
    fail.
    */
    rpc CancelInvoice (CancelInvoiceMsg) returns (CancelInvoiceResp);

    /* lncli: `addholdinvoice`
    AddHoldInvoice creates a hold invoice. It ties the invoice to the hash
    supplied in the request.
    */
    rpc AddHoldInvoice (AddHoldInvoiceRequest) returns (AddHoldInvoiceResp);

    /* lncli: `settleinvoice`
    SettleInvoice settles an accepted invoice. If the invoice is already
    settled, this call will succeed.
    */
    rpc SettleInvoice (SettleInvoiceMsg) returns (SettleInvoiceResp);

    /*
    LookupInvoiceV2 attempts to look up at invoice. An invoice can be referenced
    using either its payment hash, payment address, or set ID.
    */
    rpc LookupInvoiceV2 (LookupInvoiceMsg) returns (lnrpc.Invoice);

    /*
    HtlcModifier is a bidirectional streaming RPC that allows a client to
    intercept and modify the HTLCs that attempt to settle the given invoice. The
    server will send HTLCs of invoices to the client and the client can modify
    some aspects of the HTLC in order to pass the invoice acceptance tests.
    */
    rpc HtlcModifier (stream HtlcModifyResponse)
        returns (stream HtlcModifyRequest);
}

message CancelInvoiceMsg {
    // Hash corresponding to the (hold) invoice to cancel. When using
    // REST, this field must be encoded as base64.
    bytes payment_hash = 1;
}
message CancelInvoiceResp {
}

message AddHoldInvoiceRequest {
    /*
    An optional memo to attach along with the invoice. Used for record keeping
    purposes for the invoice's creator, and will also be set in the description
    field of the encoded payment request if the description_hash field is not
    being used.
    */
    string memo = 1;

    // The hash of the preimage
    bytes hash = 2;

    /*
    The value of this invoice in satoshis

    The fields value and value_msat are mutually exclusive.
    */
    int64 value = 3;

    /*
    The value of this invoice in millisatoshis

    The fields value and value_msat are mutually exclusive.
    */
    int64 value_msat = 10;

    /*
    Hash (SHA-256) of a description of the payment. Used if the description of
    payment (memo) is too long to naturally fit within the description field
    of an encoded payment request.
    */
    bytes description_hash = 4;

    // Payment request expiry time in seconds. Default is 86400 (24 hours).
    int64 expiry = 5;

    // Fallback on-chain address.
    string fallback_addr = 6;

    // Delta to use for the time-lock of the CLTV extended to the final hop.
    uint64 cltv_expiry = 7;

    /*
    Route hints that can each be individually used to assist in reaching the
    invoice's destination.
    */
    repeated lnrpc.RouteHint route_hints = 8;

    // Whether this invoice should include routing hints for private channels.
    bool private = 9;
}

message AddHoldInvoiceResp {
    /*
    A bare-bones invoice for a payment within the Lightning Network. With the
    details of the invoice, the sender has all the data necessary to send a
    payment to the recipient.
    */
    string payment_request = 1;

    /*
    The "add" index of this invoice. Each newly created invoice will increment
    this index making it monotonically increasing. Callers to the
    SubscribeInvoices call can use this to instantly get notified of all added
    invoices with an add_index greater than this one.
    */
    uint64 add_index = 2;

    /*
    The payment address of the generated invoice. This is also called
    the payment secret in specifications (e.g. BOLT 11). This value should
    be used in all payments for this invoice as we require it for end to end
    security.
    */
    bytes payment_addr = 3;
}

message SettleInvoiceMsg {
    // Externally discovered pre-image that should be used to settle the hold
    // invoice.
    bytes preimage = 1;
}

message SettleInvoiceResp {
}

message SubscribeSingleInvoiceRequest {
    reserved 1;

    // Hash corresponding to the (hold) invoice to subscribe to. When using
    // REST, this field must be encoded as base64url.
    bytes r_hash = 2;
}

enum LookupModifier {
    // The default look up modifier, no look up behavior is changed.
    DEFAULT = 0;

    /*
    Indicates that when a look up is done based on a set_id, then only that set
    of HTLCs related to that set ID should be returned.
    */
    HTLC_SET_ONLY = 1;

    /*
    Indicates that when a look up is done using a payment_addr, then no HTLCs
    related to the payment_addr should be returned. This is useful when one
    wants to be able to obtain the set of associated setIDs with a given
    invoice, then look up the sub-invoices "projected" by that set ID.
    */
    HTLC_SET_BLANK = 2;
}

message LookupInvoiceMsg {
    oneof invoice_ref {
        // When using REST, this field must be encoded as base64.
        bytes payment_hash = 1;
        bytes payment_addr = 2;
        bytes set_id = 3;
    }

    LookupModifier lookup_modifier = 4;
}

// CircuitKey is a unique identifier for an HTLC.
message CircuitKey {
    // The id of the channel that the is part of this circuit.
    uint64 chan_id = 1;

    // The index of the incoming htlc in the incoming channel.
    uint64 htlc_id = 2;
}

message HtlcModifyRequest {
    // The invoice the intercepted HTLC is attempting to settle. The HTLCs in
    // the invoice are only HTLCs that have already been accepted or settled,
    // not including the current intercepted HTLC.
    lnrpc.Invoice invoice = 1;

    // The unique identifier of the HTLC of this intercepted HTLC.
    CircuitKey exit_htlc_circuit_key = 2;

    // The amount in milli-satoshi that the exit HTLC is attempting to pay.
    uint64 exit_htlc_amt = 3;

    // The absolute expiry height of the exit HTLC.
    uint32 exit_htlc_expiry = 4;

    // The current block height.
    uint32 current_height = 5;

    // The wire message custom records of the exit HTLC.
    map<uint64, bytes> exit_htlc_wire_custom_records = 6;
}

message HtlcModifyResponse {
    // The circuit key of the HTLC that the client wants to modify.
    CircuitKey circuit_key = 1;

    // The modified amount in milli-satoshi that the exit HTLC is paying. This
    // value can be different from the actual on-chain HTLC amount, in case the
    // HTLC carries other valuable items, as can be the case with custom channel
    // types.
    optional uint64 amt_paid = 2;

    // This flag indicates whether the HTLCs associated with the invoices should
    // be cancelled. The interceptor client may set this field if some
    // unexpected behavior is encountered. Setting this will ignore the amt_paid
    // field.
    bool cancel_set = 3;
}
