syntax = "proto3";

import "rpc.proto";
import "signrpc/signer.proto";

package walletrpc;

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

message KeyReq {
    /**
    Is the key finger print of the root pubkey that this request is targeting.
    This allows the WalletKit to possibly serve out keys for multiple HD chains
    via public derivation.
    */
    int32 key_finger_print = 1;

    /**
    The target key family to derive a key from. In other contexts, this is
    known as the "account".
    */
    int32 key_family = 2;
}

message AddrRequest {
    // No fields, as we always give out a p2wkh address.
}
message AddrResponse {
    /**
    The address encoded using a bech32 format.
    */
    string addr = 1;
}

message Transaction {
    /**
    The raw serialized transaction.
    */
    bytes tx_hex = 1;
}
message PublishResponse {
    /**
    If blank, then no error occurred and the transaction was successfully
    published. If not the empty string, then a string representation of the
    broadcast error.

    TODO(roasbeef): map to a proper enum type
    */
    string publish_error = 1;
}

message SendOutputsRequest {
    /**
    The number of satoshis per kilo weight that should be used when crafting
    this transaction.
    */
    int64 sat_per_kw = 1;

    /**
    A slice of the outputs that should be created in the transaction produced.
    */
    repeated signrpc.TxOut outputs = 2;
}
message SendOutputsResponse {
    /**
    The serialized transaction sent out on the network.
    */
    bytes raw_tx = 1;
}

message EstimateFeeRequest {
    /**
    The number of confirmations to shoot for when estimating the fee.
    */
    int32 conf_target = 1;
}
message EstimateFeeResponse {
    /**
    The amount of satoshis per kw that should be used in order to reach the
    confirmation target in the request.
    */
    int64 sat_per_kw = 1;
}

enum WitnessType {
    UNKNOWN_WITNESS = 0;

    /*
    A witness that allows us to spend the output of a commitment transaction
    after a relative lock-time lockout.
    */
    COMMITMENT_TIME_LOCK = 1;

    /*
    A witness that allows us to spend a settled no-delay output immediately on a
    counterparty's commitment transaction.
    */
    COMMITMENT_NO_DELAY = 2;

    /*
    A witness that allows us to sweep the settled output of a malicious
    counterparty's who broadcasts a revoked commitment transaction.
    */
    COMMITMENT_REVOKE = 3;

    /*
    A witness that allows us to sweep an HTLC which we offered to the remote
    party in the case that they broadcast a revoked commitment state.
    */
    HTLC_OFFERED_REVOKE = 4;

    /*
    A witness that allows us to sweep an HTLC output sent to us in the case that
    the remote party broadcasts a revoked commitment state.
    */
    HTLC_ACCEPTED_REVOKE = 5;

    /*
    A witness that allows us to sweep an HTLC output that we extended to a
    party, but was never fulfilled.  This HTLC output isn't directly on the
    commitment transaction, but is the result of a confirmed second-level HTLC
    transaction. As a result, we can only spend this after a CSV delay.
    */
    HTLC_OFFERED_TIMEOUT_SECOND_LEVEL = 6;

    /*
    A witness that allows us to sweep an HTLC output that was offered to us, and
    for which we have a payment preimage. This HTLC output isn't directly on our
    commitment transaction, but is the result of confirmed second-level HTLC
    transaction. As a result, we can only spend this after a CSV delay.
    */
    HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL = 7;

    /*
    A witness that allows us to sweep an HTLC that we offered to the remote
    party which lies in the commitment transaction of the remote party. We can
    spend this output after the absolute CLTV timeout of the HTLC as passed.
    */
    HTLC_OFFERED_REMOTE_TIMEOUT = 8;

    /*
    A witness that allows us to sweep an HTLC that was offered to us by the
    remote party. We use this witness in the case that the remote party goes to
    chain, and we know the pre-image to the HTLC. We can sweep this without any
    additional timeout.
    */
    HTLC_ACCEPTED_REMOTE_SUCCESS = 9;

    /*
    A witness that allows us to sweep an HTLC from the remote party's commitment
    transaction in the case that the broadcast a revoked commitment, but then
    also immediately attempt to go to the second level to claim the HTLC.
    */
    HTLC_SECOND_LEVEL_REVOKE = 10;

    /*
    A witness type that allows us to spend a regular p2wkh output that's sent to
    an output which is under complete control of the backing wallet.
    */
    WITNESS_KEY_HASH = 11;

    /*
    A witness type that allows us to sweep an output that sends to a nested P2SH
    script that pays to a key solely under our control.
    */
    NESTED_WITNESS_KEY_HASH = 12;

    /*
    A witness type that allows us to spend our anchor on the commitment
    transaction.
    */
    COMMITMENT_ANCHOR = 13;
}

message PendingSweep {
    // The outpoint of the output we're attempting to sweep.
    lnrpc.OutPoint outpoint = 1;

    // The witness type of the output we're attempting to sweep.
    WitnessType witness_type = 2;

    // The value of the output we're attempting to sweep.
    uint32 amount_sat = 3;

    /*
    The fee rate we'll use to sweep the output. The fee rate is only determined
    once a sweeping transaction for the output is created, so it's possible for
    this to be 0 before this.
    */
    uint32 sat_per_byte = 4;

    // The number of broadcast attempts we've made to sweep the output.
    uint32 broadcast_attempts = 5;

    /*
    The next height of the chain at which we'll attempt to broadcast the
    sweep transaction of the output.
    */
    uint32 next_broadcast_height = 6;

    // The requested confirmation target for this output.
    uint32 requested_conf_target = 8;

    // The requested fee rate, expressed in sat/byte, for this output.
    uint32 requested_sat_per_byte = 9;

    /**
    Whether this input must be force-swept. This means that it is swept even
    if it has a negative yield.
    */
    bool force = 7;
}

message PendingSweepsRequest {
}

message PendingSweepsResponse {
    /*
    The set of outputs currently being swept by lnd's central batching engine.
    */
    repeated PendingSweep pending_sweeps = 1;
}

message BumpFeeRequest {
    // The input we're attempting to bump the fee of.
    lnrpc.OutPoint outpoint = 1;

    // The target number of blocks that the input should be spent within.
    uint32 target_conf = 2;

    /*
    The fee rate, expressed in sat/byte, that should be used to spend the input
    with.
    */
    uint32 sat_per_byte = 3;

    /**
    Whether this input must be force-swept. This means that it is swept even
    if it has a negative yield.
    */
    bool force = 4;
}

message BumpFeeResponse {
}

service WalletKit {
    /**
    DeriveNextKey attempts to derive the *next* key within the key family
    (account in BIP43) specified. This method should return the next external
    child within this branch.
    */
    rpc DeriveNextKey (KeyReq) returns (signrpc.KeyDescriptor);

    /**
    DeriveKey attempts to derive an arbitrary key specified by the passed
    KeyLocator.
    */
    rpc DeriveKey (signrpc.KeyLocator) returns (signrpc.KeyDescriptor);

    /**
    NextAddr returns the next unused address within the wallet.
    */
    rpc NextAddr (AddrRequest) returns (AddrResponse);

    /**
    PublishTransaction attempts to publish the passed transaction to the
    network. Once this returns without an error, the wallet will continually
    attempt to re-broadcast the transaction on start up, until it enters the
    chain.
    */
    rpc PublishTransaction (Transaction) returns (PublishResponse);

    /**
    SendOutputs is similar to the existing sendmany call in Bitcoind, and
    allows the caller to create a transaction that sends to several outputs at
    once. This is ideal when wanting to batch create a set of transactions.
    */
    rpc SendOutputs (SendOutputsRequest) returns (SendOutputsResponse);

    /**
    EstimateFee attempts to query the internal fee estimator of the wallet to
    determine the fee (in sat/kw) to attach to a transaction in order to
    achieve the confirmation target.
    */
    rpc EstimateFee (EstimateFeeRequest) returns (EstimateFeeResponse);

    /*
    PendingSweeps returns lists of on-chain outputs that lnd is currently
    attempting to sweep within its central batching engine. Outputs with similar
    fee rates are batched together in order to sweep them within a single
    transaction.

    NOTE: Some of the fields within PendingSweepsRequest are not guaranteed to
    remain supported. This is an advanced API that depends on the internals of
    the UtxoSweeper, so things may change.
    */
    rpc PendingSweeps (PendingSweepsRequest) returns (PendingSweepsResponse);

    /*
    BumpFee bumps the fee of an arbitrary input within a transaction. This RPC
    takes a different approach than bitcoind's bumpfee command. lnd has a
    central batching engine in which inputs with similar fee rates are batched
    together to save on transaction fees. Due to this, we cannot rely on
    bumping the fee on a specific transaction, since transactions can change at
    any point with the addition of new inputs. The list of inputs that
    currently exist within lnd's central batching engine can be retrieved
    through the PendingSweeps RPC.

    When bumping the fee of an input that currently exists within lnd's central
    batching engine, a higher fee transaction will be created that replaces the
    lower fee transaction through the Replace-By-Fee (RBF) policy. If it

    This RPC also serves useful when wanting to perform a Child-Pays-For-Parent
    (CPFP), where the child transaction pays for its parent's fee. This can be
    done by specifying an outpoint within the low fee transaction that is under
    the control of the wallet.

    The fee preference can be expressed either as a specific fee rate or a delta
    of blocks in which the output should be swept on-chain within. If a fee
    preference is not explicitly specified, then an error is returned.

    Note that this RPC currently doesn't perform any validation checks on the
    fee preference being provided. For now, the responsibility of ensuring that
    the new fee preference is sufficient is delegated to the user.
    */
    rpc BumpFee (BumpFeeRequest) returns (BumpFeeResponse);
}