LIGHTNING-LISTPEERCHANNELS(7)

πŸ“¦
version 26.06.9 Β· 2 versions
, in nixpkgs unstable

πŸ’… LIGHTNING-LISTPEERCHANNELS(7) β€” the manpage, but make it cute ✨

okay bestie, this is section 7 of the lightning manual, and it's literally the page about listpeerchannels, so buckle up πŸŽ€


🌸 NAME 🌸

listpeerchannels β€” the command that hands you all the data on the channels of your connected lightning nodes 🫢


✨ SYNOPSIS ✨

listpeerchannels [id] [short_channel_id] [channel_id]

πŸ’– DESCRIPTION πŸ’–

So first of all, this command was added in v23.02 β€” vintage, iconic, we love her πŸ‘‘

The listpeerchannels RPC command returns a list of this node's channels. That's the whole ~concept~ πŸ’«

By default you get data for all the known channels β€” including the ones to peers who are currently connected, and the ones to peers who are disconnected but still have open channels. like yeah they're not answering your texts rn but the channel is literally still there, no cap 😭

At most one of id, short_channel_id or channel_id may be provided as a filter. If more than one is provided, the command fails with an error. that's your vibe check: pick one filter, bestie, don't be greedy πŸ™ˆ

  • id (pubkey, optional) β€” if supplied, limits the channels to just the peer with the given ID, if it exists. Cannot be used with short_channel_id or channel_id.
  • short_channel_id (short_channel_id, optional) β€” if supplied, limits the channels to just this short_channel_id (or local alias), if it exists. Cannot be used with id or channel_id. (added v25.05 ✨)
  • channel_id (hash, optional) β€” if supplied, limits the channels to just this channel_id, if it exists. Cannot be used with id or short_channel_id. (added v26.04 🌟)

πŸ‘‘ RETURN VALUE πŸ‘‘

On success, an object containing channels is returned. It is an array of objects, where each object contains β€” and yeah, it's a long list, but we're reading all of it because I refuse to skip parts πŸ’…

  • peer_id (pubkey) β€” node public key. that's their identity, respect it 🫑
  • peer_connected (boolean) β€” a boolean flag that is set to true if the peer is online. like a little green dot but in JSON form 🟒
  • state (string) (one of "OPENINGD", "CHANNELD_AWAITING_LOCKIN", "CHANNELD_NORMAL", "CHANNELD_SHUTTING_DOWN", "CLOSINGD_SIGEXCHANGE", "CLOSINGD_COMPLETE", "AWAITING_UNILATERAL", "FUNDING_SPEND_SEEN", "ONCHAIN", "DUALOPEND_OPEN_INIT", "DUALOPEND_AWAITING_LOCKIN", "CHANNELD_AWAITING_SPLICE", "DUALOPEND_OPEN_COMMITTED", "DUALOPEND_OPEN_COMMIT_READY") β€” the channel state. and in particular, CHANNELD_NORMAL means the channel can be used normally β€” that's the main character state, the one you want ✨
  • opener (string) (one of "local", "remote") β€” who initiated the channel. who texted first, essentially πŸ’Œ
  • features (array of strings) β€” the feature list, and each entry is:
    • (string, optional) (one of "option_static_remotekey", "option_anchor_outputs", "option_anchors", "option_scid_alias", "option_zeroconf") β€” BOLT #9 features which apply to this channel.
  • reestablished (boolean, optional) β€” a boolean flag that is set to true if we have successfully exchanged reestablish messages with this connection. (added v24.02) the reunion arc πŸ₯Ή
  • scratch_txid (txid, optional) β€” the txid we would use if we went onchain now.
  • channel_type (object, optional) β€” Channel_type as negotiated with peer. (added v23.05) β€”β€” okay this one's got layers, stay with me 🧚
    • bits (array of u32s) β€” each bit set in this channel_type.:
      • (u32, optional) β€” bit number.
    • names (array of strings) β€” feature name for each bit set in this channel_type. Note that anchors_zero_fee_htlc_tx is a deprecated synonym for anchors. (yes, deprecated β€” clock that πŸ•°οΈ):
      • (string, optional) (one of "static_remotekey/even", "anchor_outputs/even", "anchors/even", "anchors_zero_fee_htlc_tx/even", "scid_alias/even", "zeroconf/even") β€” name of feature bit.
  • updates (object, optional) β€” latest gossip updates sent/received. (added v24.02) gossip!! the tea!! 🍡
    • local (object) β€” our gossip for channel. (added v24.02):
      • htlc_minimum_msat (msat) β€” minimum msat amount we allow. (added v24.02)
      • htlc_maximum_msat (msat) β€” maximum msat amount we allow. (added v24.02)
      • cltv_expiry_delta (u32) β€” blocks delay required between incoming and outgoing HTLCs. (added v24.02)
      • fee_base_msat (msat) β€” amount we charge to use the channel. (added v24.02) πŸ’Έ
      • fee_proportional_millionths (u32) β€” amount we charge to use the channel in parts-per-million. (added v24.02)
    • remote (object, optional) β€” peer's gossip for channel. (added v24.02):
      • htlc_minimum_msat (msat) β€” minimum msat amount they allow. (added v24.02)
      • htlc_maximum_msat (msat) β€” maximum msat amount they allow. (added v24.02)
      • cltv_expiry_delta (u32) β€” blocks delay required between incoming and outgoing HTLCs. (added v24.02)
      • fee_base_msat (msat) β€” amount they charge to use the channel. (added v24.02)
      • fee_proportional_millionths (u32) β€” amount they charge to use the channel in parts-per-million. (added v24.02)
  • ignore_fee_limits (boolean, optional) β€” set if we allow this peer to set fees to anything they want. (added v23.08) chaos mode activated πŸ’€
  • lost_state (boolean, optional) β€” set if we are fallen behind i.e. lost some channel state. (added v24.02) not the flop era 😭
  • feerate (object, optional) β€” feerates for the current tx.:
    • perkw (u32) β€” feerate per 1000 weight (i.e kSipa).
    • perkb (u32) β€” feerate per 1000 virtual bytes.
  • owner (string, optional) β€” the current subdaemon controlling this connection.
  • short_channel_id (short_channel_id, optional) β€” the short_channel_id (once locked in).
  • direction (u32, optional) β€” the direction of the channel (i.e. 0 if we are the lesser node id, 1 if we are the greater).
  • channel_id (hash, optional) β€” the full channel_id (funding txid Xored with output number).
  • funding_txid (txid, optional) β€” ID of the funding transaction.
  • funding_outnum (u32, optional) β€” the 0-based output number of the funding transaction which opens the channel.
  • initial_feerate (string, optional) β€” for inflight opens, the first feerate used to initiate the channel open.
  • last_feerate (string, optional) β€” for inflight opens, the most recent feerate used on the channel open.
  • next_feerate (string, optional) β€” for inflight opens, the next feerate we'll use for the channel open. Omitted if last_feerate admits no valid next feerate.
  • next_fee_step (u32, optional) β€” inflight opens only, bestie: this is the next feerate step we're gonna use for the channel open. πŸ’Έ
  • inflight (array of objects, optional) β€” the current candidate funding transactions, like the shortlist of txs that might actually open this channel. Each one's got:
    • funding_txid (txid) β€” the ID of the funding transaction.
    • funding_outnum (u32) β€” the 0-based output number of the funding transaction that opens the channel.
    • feerate (string) β€” the feerate for this funding transaction, per-1000-weight, with kpw tacked on the end.
    • total_funding_msat (msat) β€” total amount in the channel.
    • splice_amount (integer) β€” how many sats we're splicing in or out. (added v23.08)
    • our_funding_msat (msat) β€” how much of the channel is ours.
    • scratch_txid (txid, optional) β€” the commitment transaction txid we'd be using if we went onchain, like, right now.
  • close_to (hex, optional) β€” the ScriptPubkey we have to close to if we mutual close.
  • private (boolean, optional) β€” if True, we will not announce this channel. 🀫
  • closer (string, optional) (one of "local", "remote") β€” who initiated the channel close. Only present if closing, obvi.
  • funding (object, optional) β€” the whole "who paid for what" receipts:
    • local_funds_msat (msat) β€” amount of the channel we funded.
    • remote_funds_msat (msat) β€” amount of the channel they funded.
    • pushed_msat (msat, optional) β€” amount pushed from opener to peer.
    • fee_paid_msat (msat, optional) β€” amount we paid the peer at open.
    • fee_rcvd_msat (msat, optional) β€” amount we were paid by the peer at open.
    • psbt (string, optional) β€” the PSBT (may be non-final or unsigned) we should use to open the channel, if any. This is initially from fundchannel_complete, but will be updated with if sendpsbt is called with an updated PSBT. (added v25.12)
    • withheld (boolean, optional) β€” True if fundchannel_complete told us it will not broadcast the funding transaction (so we know not to bother with any other onchain transactions in the case of this channel). This is set to false if sendpsbt is send on the above PSBT. (added v25.12)
  • to_us_msat (msat, optional) β€” how much of the channel is owed to us. 🫢
  • min_to_us_msat (msat, optional) β€” the least amount ever owed to us. If the peer were to successfully steal from us, this is the amount we would still retain. Not the vibe, but good to know.
  • max_to_us_msat (msat, optional) β€” the most amount ever owed to us. If we were to successfully steal from the peer, this is the amount we could potentially get. 😈
  • total_msat (msat, optional) β€” total amount in the channel.
  • fee_base_msat (msat, optional) β€” amount we charge to use the channel.
  • fee_proportional_millionths (u32, optional) β€” amount we charge to use the channel, in parts-per-million.
  • dust_limit_msat (msat, optional) β€” the minimum amount for an output on the channel transactions. Anything under this is literally dust, hence the name, slay.
  • their_max_htlc_value_in_flight_msat (msat, optional) β€” the cap on the total value of outstanding HTLCs offered to the remote node. This limits the total amount in flight we can send through this channel. (added v25.02)
  • our_max_htlc_value_in_flight_msat (msat, optional) β€” the cap on the total value of outstanding HTLCs we accept from the remote node. This limits the total amount in flight we can receive through this channel. (added v25.02)
  • their_reserve_msat (msat, optional) β€” the minimum we insist they keep in the channel. If they have less than this in the channel, they cannot send to us on that channel. The default is 1% of the total channel capacity. πŸ‘‘
  • our_reserve_msat (msat, optional) β€” the minimum they insist we keep in the channel. If you have less than this in the channel, you cannot send out via this channel.
  • spendable_msat (msat, optional) β€” an estimate of the total we could send through the channel. Heads up though: it can be wrong, because adding HTLCs requires an increase in fees paid to onchain miners, and onchain fees change dynamically according to onchain activity. So like, vibe estimate, not gospel. πŸ’€
  • receivable_msat (msat, optional) β€” an estimate of the total the peer could send through the channel.
  • minimum_htlc_in_msat (msat, optional) β€” the minimum amount HTLC we accept.
  • minimum_htlc_out_msat (msat, optional) β€” the minimum amount HTLC we will send.
  • maximum_htlc_out_msat (msat, optional) β€” the maximum amount HTLC we will send.
  • their_to_self_delay (u32, optional) β€” the number of blocks before they can take their funds if they unilateral close.
  • our_to_self_delay (u32, optional) β€” the number of blocks before we can take our funds if we unilateral close.
  • max_accepted_htlcs (u32, optional) β€” the maximum number of incoming HTLCs we will accept at once.
  • alias (object, optional) β€” the cute lil nicknames for this channel:
    • local (short_channel_id, optional) β€” an alias assigned by this node to this channel, used for outgoing payments.
    • remote (short_channel_id, optional) β€” an alias assigned by the remote node to this channel, usable in routehints and invoices.
  • state_changes (array of objects, optional) β€” the prior state changes, like a whole character arc for the channel. Each entry:
    • timestamp (string) β€” UTC timestamp of the form YYYY-mm-ddTHH:MM:SS.%03dZ.
    • old_state (string) (one of "OPENINGD", "CHANNELD_AWAITING_LOCKIN", "CHANNELD_NORMAL", "CHANNELD_SHUTTING_DOWN", "CLOSINGD_SIGEXCHANGE", "CLOSINGD_COMPLETE", "AWAITING_UNILATERAL", "FUNDING_SPEND_SEEN", "ONCHAIN", "DUALOPEND_OPEN_INIT", "DUALOPEND_AWAITING_LOCKIN", "DUALOPEND_OPEN_COMMITTED", "DUALOPEND_OPEN_COMMIT_READY", "CHANNELD_AWAITING_SPLICE") β€” previous state.
    • new_state (string) (one of "OPENINGD", "CHANNELD_AWAITING_LOCKIN", "CHANNELD_NORMAL", "CHANNELD_SHUTTING_DOWN", "CLOSINGD_SIGEXCHANGE", "CLOSINGD_COMPLETE", "AWAITING_UNILATERAL", "FUNDING_SPEND_SEEN", "ONCHAIN", "DUALOPEND_OPEN_INIT", "DUALOPEND_AWAITING_LOCKIN", "DUALOPEND_OPEN_COMMITTED", "DUALOPEND_OPEN_COMMIT_READY", "CHANNELD_AWAITING_SPLICE") β€” new state.
    • cause (string) (one of "unknown", "local", "user", "remote", "protocol", "onchain") β€” what caused the change.
    • message (string) β€” human-readable explanation. finally, something in plain English ✨
  • status (array of strings, optional) β€” the billboard:
    • (string, optional) β€” billboard log of significant changes.
  • in_payments_offered (u64, optional) β€” number of incoming payment attempts.
  • in_offered_msat (msat, optional) β€” total amount of incoming payment attempts.
  • in_payments_fulfilled (u64, optional) β€” number of successful incoming payment attempts.
  • in_fulfilled_msat (msat, optional) β€” total amount of successful incoming payment attempts.
  • out_payments_offered (u64, optional) β€” number of outgoing payment attempts.
  • out_offered_msat (msat, optional) β€” total amount of outgoing payment attempts.
  • out_payments_fulfilled (u64, optional) β€” number of successful outgoing payment attempts.
  • out_fulfilled_msat (msat, optional) β€” total amount of successful outgoing payment attempts.
  • last_stable_connection (u64, optional) β€” the last time we reestablished the open channel and stayed connected for 1 minute. (added v24.02) honestly a whole achievement πŸŽ€
  • htlcs (array of objects, optional) β€” the HTLCs currently in this channel. Each one:
    • direction (string) (one of "in", "out") β€” whether it came from the peer, or is going to the peer. (added v23.02)
    • id (u64) β€” unique ID for this htlc on this channel in this direction.
    • amount_msat (msat) β€” amount sent/received for this HTLC.
    • expiry (u32) β€” the block this HTLC expires at (after which an in direction HTLC will be returned to the peer, an out returned to us). If this expiry is too close, lightningd(8) will automatically unilaterally close the channel in order to enforce the timeout onchain. so, y'know, no pressure or anything 😭
    • payment_hash (hash) β€” the hash of the payment_preimage which will prove payment.
    • local_trimmed (boolean, optional) (always true) β€” if this is too small to enforce onchain; it doesn't appear in the commitment transaction and will not be enforced in a unilateral close. Generally true if the HTLC (after subtracting onchain fees) is below the dust_limit_msat for the channel.
    • status (string, optional) β€” set if this HTLC is currently waiting on a hook (and shows what plugin). πŸͺ
okay so the htlcs objects get a lil conditional moment, depending on which way the HTLC is going:
  • If direction is "out":
    • state (string) (one of "SENT_ADD_HTLC", "SENT_ADD_COMMIT", "RCVD_ADD_REVOCATION", "RCVD_ADD_ACK_COMMIT", "SENT_ADD_ACK_REVOCATION", "RCVD_REMOVE_HTLC", "RCVD_REMOVE_COMMIT", "SENT_REMOVE_REVOCATION", "SENT_REMOVE_ACK_COMMIT", "RCVD_REMOVE_ACK_REVOCATION") β€” status of the HTLC.
  • If direction is "in":
    • state (string) (one of "RCVD_ADD_HTLC", "RCVD_ADD_COMMIT", "SENT_ADD_REVOCATION", "SENT_ADD_ACK_COMMIT", "RCVD_ADD_ACK_REVOCATION", "SENT_REMOVE_HTLC", "SENT_REMOVE_COMMIT", "RCVD_REMOVE_REVOCATION", "RCVD_REMOVE_ACK_COMMIT", "SENT_REMOVE_ACK_REVOCATION") β€” status of the HTLC.

And there's more conditional goodness, bestie β€” these show up only when their trigger field is around:

  • If peer_connected is true:
    • reestablished (boolean, optional) β€” True if we have successfully exchanged reestablish messages on this connection.
  • If close_to is present:
    • close_to_addr (string, optional) β€” the bitcoin address we will close to (present if close_to_addr is a standardized address).
  • If scratch_txid is present:
    • last_tx_fee_msat (msat) β€” fee attached to this the current tx.
  • If short_channel_id is present:
    • direction (u32) β€” 0 if we're the lesser node_id, 1 if we're the greater (as used in BOLT #7 channel_update). (added v23.02)
  • If inflight is present:
    • initial_feerate (string) β€” the feerate for the initial funding transaction, per-1000-weight, with kpw appended.
    • last_feerate (string) β€” the feerate for the latest funding transaction, per-1000-weight, with kpw appended.
    • next_feerate (string, optional) β€” the minimum feerate for the next funding transaction, per-1000-weight, with kpw appended. Omitted if last_feerate admits no valid next feerate.

The state field values (and old_state / new_state) are worth describing further:

  • OPENINGD β€” the channel funding protocol with the peer is literally happening right now and both sides are hashing out the parameters πŸŽ€
  • DUALOPEND_OPEN_INIT β€” same energy as OPENINGD, but for v2 connections that are doing collaborative opens ✨
  • DUALOPEND_OPEN_COMMIT_READY β€” again, like OPENINGD, but for v2 connections using collaborative opens. Bestie, you are ready to send your commitment signed to your peer πŸ’…
  • DUALOPEND_OPEN_COMMITTED β€” like OPENINGD, but for v2 connections using collaborative opens. You've gotten an initial signed commitment from your peer, slay 🫢
  • CHANNELD_AWAITING_LOCKIN / DUALOPEND_AWAITING_LOCKIN β€” the peer and you have agreed on channel parameters and are just sitting there waiting for the channel funding transaction to be confirmed deeply (that's the original protocol and the collaborative open protocol respectively, iykyk). Both you and the peer have to acknowledge the channel funding transaction as confirmed deeply before anybody moves to the next state. Bonus: you can bump the onchain fee for channels in DUALOPEND_AWAITING_LOCKIN using lightning-openchannel_bump(7) πŸ”₯
  • CHANNELD_NORMAL β€” the channel can be used for normal payments. main character energy, honestly πŸ‘‘
  • CHANNELD_SHUTTING_DOWN β€” a mutual close was requested (by you or by the peer) and both of you are waiting for the in-flight HTLCs to either fail or succeed. The channel can no longer be used for normal payments and forwarding. The mutual close only proceeds once every HTLC in the channel has been fulfilled or failed 🌈
  • CLOSINGD_SIGEXCHANGE β€” you and the peer are negotiating the mutual close onchain fee. haggling arc πŸ’€
  • CLOSINGD_COMPLETE β€” you and the peer have agreed on the mutual close onchain fee and are now awaiting the mutual close getting confirmed deeply ⭐
  • AWAITING_UNILATERAL β€” you initiated a unilateral close, and now you're just waiting for the peer-selected unilateral close timeout to complete πŸ™ˆ
  • FUNDING_SPEND_SEEN β€” you saw the funding transaction getting spent (usually the peer initiated a unilateral close) and you will now determine what exactly happened, i.e. whether it was a theft attempt 😭
  • ONCHAIN β€” you saw the funding transaction getting spent and now you know what happened, i.e. whether it was a proper unilateral close by the peer or a theft attempt πŸ¦‹

πŸ’€ ERRORS πŸ’€

When something goes wrong, the returned object comes with code and message properties, and code is gonna be one of these bad boys:

  • -32602 β€” if the given parameters are wrong. classic. not the vibe πŸ™ˆ

✨ AUTHOR ✨

Michael Hawkins michael.hawkins@protonmail.com.


πŸŽ€ SEE ALSO πŸŽ€

lightning-connect(7), lightning-fundchannel_start(7)


🌸 RESOURCES 🌸

Main web site: https://github.com/ElementsProject/lightning

Lightning RFC site (BOLT #9): https://github.com/lightningnetwork/lightning-rfc/blob/master/09-fea‐ tures.md


πŸ¦‹ EXAMPLES πŸ¦‹

Example 1:

Request:

$ lightning-cli listpeerchannels -k "id"="nodeid020202020202020202020202020202020202020202020202020202020202"
{
  "id": "example:listpeerchannels#1",
  "method": "listpeerchannels",
  "params": {
    "id": "nodeid020202020202020202020202020202020202020202020202020202020202"
  }
}

Response:

{
  "channels": [
    {
      "peer_id": "nodeid020202020202020202020202020202020202020202020202020202020202",
      "peer_connected": true,
      "reestablished": true,
      "channel_type": {
        "bits": [
          12,
          22
        ],
        "names": [
          "static_remotekey/even",
          "anchors/even"
        ]
      },
      "updates": {
        "local": {
          "htlc_minimum_msat": 0,
          "htlc_maximum_msat": 990000000,
          "cltv_expiry_delta": 6,
          "fee_base_msat": 1,
          "fee_proportional_millionths": 10
        },
        "remote": {
          "htlc_minimum_msat": 0,
          "htlc_maximum_msat": 990000000,
          "cltv_expiry_delta": 6,
          "fee_base_msat": 1,
          "fee_proportional_millionths": 10
        }
      },
      "last_stable_connection": 1738510000,
      "state": "CHANNELD_NORMAL",
      "scratch_txid": "scratchid1010101010101010101010101010101010101010101010101010101",
      "last_tx_fee_msat": 4867000,
      "lost_state": false,
      "feerate": {
        "perkw": 3755,
        "perkb": 15020
      },
      "owner": "channeld",
      "short_channel_id": "109x1x1",
      "direction": 1,
      "channel_id": "channelid0120000120000120000120000120000120000120000120000120000",
      "funding_txid": "channeltxid120000120000120000120000120000120000120000120000120000",
      "funding_outnum": 1,
      "close_to_addr": "bcrt1p8c0ku4mpxq3443rss8e6rjwamztvv8yxvmxtetal5d0n6v39rlwqvfqy6n",
      "close_to": "51203e1f6e576130235ac47081f3a1c9ddd896c61c8666ccbcafbfa35f3d32251fdc",
      "private": false,
      "opener": "local",
      "alias": {
        "local": "30000001x60000001x60001",
        "remote": "10000001x20000001x30001"
      },
      "features": [
        "option_static_remotekey",
        "option_anchors"
      ],
      "funding": {
        "local_funds_msat": 1000000000,
        "remote_funds_msat": 0,
        "pushed_msat": 0
      },
      "to_us_msat": 390492790,
      "min_to_us_msat": 390492790,
      "max_to_us_msat": 1000000000,
      "total_msat": 1000000000,
      "fee_base_msat": 1,
      "fee_proportional_millionths": 10,
      "dust_limit_msat": 546000,
      "their_max_htlc_value_in_flight_msat": 18446744073709552000,
      "our_max_htlc_value_in_flight_msat": 18446744073709552000,
      "their_reserve_msat": 10000000,
      "our_reserve_msat": 10000000,
      "spendable_msat": 363951708,
      "receivable_msat": 599507210,
      "minimum_htlc_in_msat": 0,
      "minimum_htlc_out_msat": 0,
      "maximum_htlc_out_msat": 990000000,
      "their_to_self_delay": 5,
      "our_to_self_delay": 5,
      "max_accepted_htlcs": 483,
      "state_changes": [
        {
          "timestamp": "2024-10-10T00:01:00.000Z",
          "old_state": "DUALOPEND_OPEN_COMMITTED",
          "new_state": "DUALOPEND_AWAITING_LOCKIN",
          "cause": "user",
          "message": "Sigs exchanged, waiting for lock-in"
        },
        {
          "timestamp": "2024-10-10T00:02:00.000Z",
          "old_state": "DUALOPEND_AWAITING_LOCKIN",
          "new_state": "CHANNELD_NORMAL",
          "cause": "user",
          "message": "Lockin complete"
        }
      ],
      "status": [
        "CHANNELD_NORMAL:Channel ready for use."
      ],
      "in_payments_offered": 1,
      "in_offered_msat": 1000000,
      "in_payments_fulfilled": 1,
      "in_fulfilled_msat": 1000000,
      "out_payments_offered": 22,
      "out_offered_msat": 665528797,
      "out_payments_fulfilled": 16,
      "out_fulfilled_msat": 610507210,
      "htlcs": [
        {
          "direction": "out",
          "id": 17,
          "amount_msat": 4000082,
          "expiry": 181,
          "payment_hash": "paymenthashdelpay30303030303030303030303030303030303030303030303",
          "state": "SENT_ADD_ACK_REVOCATION"
        }
      ]
    }
  ]
}

Example 2:

Request:

$ lightning-cli listpeerchannels
{
  "id": "example:listpeerchannels#2",
  "method": "listpeerchannels",
  "params": {}
}

Response:

…bestie, buckle up, because here's the rest of that output and it is a LOT πŸ’… It's an object with a "channels" array, and channel number one is absolutely living its best main character life while channel number two is fully onchain and kind of in its flop era (affectionate). Every single field, exactly as it prints:

{
  "channels": [
    {
      "peer_id": "nodeid020202020202020202020202020202020202020202020202020202020202",
      "peer_connected": true,
      "reestablished": true,
      "channel_type": {
        "bits": [
          12,
          22
        ],
        "names": [
          "static_remotekey/even",
          "anchors/even"
        ]
      },
      "updates": {
        "local": {
          "htlc_minimum_msat": 0,
          "htlc_maximum_msat": 990000000,
          "cltv_expiry_delta": 6,
          "fee_base_msat": 1,
          "fee_proportional_millionths": 10
        },
        "remote": {
          "htlc_minimum_msat": 0,
          "htlc_maximum_msat": 990000000,
          "cltv_expiry_delta": 6,
          "fee_base_msat": 1,
          "fee_proportional_millionths": 10
        }
      },
      "last_stable_connection": 1738520000,
      "state": "CHANNELD_NORMAL",
      "scratch_txid": "scratchid2020202020202020202020202020202020202020202020202020202",
      "last_tx_fee_msat": 4867000,
      "lost_state": false,
      "feerate": {
        "perkw": 3755,
        "perkb": 15020
      },
      "owner": "channeld",
      "short_channel_id": "109x1x1",
      "direction": 1,
      "channel_id": "channelid0120000120000120000120000120000120000120000120000120000",
      "funding_txid": "channeltxid120000120000120000120000120000120000120000120000120000",
      "funding_outnum": 1,
      "close_to_addr": "bcrt1pcl00020002000200020002000200020002000200020002000200020002",
      "close_to": "db2dec31020202020202020202020202020202020202020202020202020202020202",
      "private": false,
      "opener": "local",
      "alias": {
        "local": "30000002x60000002x60002",
        "remote": "10000002x20000002x30002"
      },
      "features": [
        "option_static_remotekey",
        "option_anchors"
      ],
      "funding": {
        "local_funds_msat": 1000000000,
        "remote_funds_msat": 0,
        "pushed_msat": 0
      },
      "to_us_msat": 390492790,
      "min_to_us_msat": 390492790,
      "max_to_us_msat": 1000000000,
      "total_msat": 1000000000,
      "fee_base_msat": 1,
      "fee_proportional_millionths": 10,
      "dust_limit_msat": 546000,
      "their_max_htlc_value_in_flight_msat": 18446744073709552000,
      "our_max_htlc_value_in_flight_msat": 18446744073709552000,
      "their_reserve_msat": 10000000,
      "our_reserve_msat": 10000000,
      "spendable_msat": 363951708,
      "receivable_msat": 599507210,
      "minimum_htlc_in_msat": 0,
      "minimum_htlc_out_msat": 0,
      "maximum_htlc_out_msat": 990000000,
      "their_to_self_delay": 5,
      "our_to_self_delay": 5,
      "max_accepted_htlcs": 483,
      "state_changes": [
        {
          "timestamp": "2024-10-10T00:01:00.000Z",
          "old_state": "DUALOPEND_OPEN_COMMITTED",
          "new_state": "DUALOPEND_AWAITING_LOCKIN",
          "cause": "user",
          "message": "Sigs exchanged, waiting for lock-in"
        },
        {
          "timestamp": "2024-10-10T00:02:00.000Z",
          "old_state": "DUALOPEND_AWAITING_LOCKIN",
          "new_state": "CHANNELD_NORMAL",
          "cause": "user",
          "message": "Lockin complete"
        }
      ],
      "status": [
        "CHANNELD_NORMAL:Channel ready for use."
      ],
      "in_payments_offered": 1,
      "in_offered_msat": 1000000,
      "in_payments_fulfilled": 1,
      "in_fulfilled_msat": 1000000,
      "out_payments_offered": 22,
      "out_offered_msat": 665528797,
      "out_payments_fulfilled": 16,
      "out_fulfilled_msat": 610507210,
      "htlcs": [
        {
          "direction": "out",
          "id": 17,
          "amount_msat": 4000082,
          "expiry": 181,
          "payment_hash": "paymenthashdelpay30303030303030303030303030303030303030303030303",
          "state": "SENT_ADD_ACK_REVOCATION"
        }
      ]
    },
    {
      "peer_id": "nodeid030303030303030303030303030303030303030303030303030303030303",
      "peer_connected": false,
      "channel_type": {
        "bits": [
          12,
          22
        ],
        "names": [
          "static_remotekey/even",
          "anchors/even"
        ]
      },
      "updates": {
        "local": {
          "htlc_minimum_msat": 0,
          "htlc_maximum_msat": 19454000,
          "cltv_expiry_delta": 6,
          "fee_base_msat": 1,
          "fee_proportional_millionths": 10
        }
      },
      "state": "ONCHAIN",
      "scratch_txid": "scratchid2030303030303030303030303030303030303030303030303030303",
      "last_tx_fee_msat": 2250000,
      "lost_state": false,
      "feerate": {
        "perkw": 3750,
        "perkb": 15000
      },
      "owner": "onchaind",
      "direction": 0,
      "channel_id": "channelid1100011000110001100011000110001100011000110001100011000",
      "funding_txid": "channeltxid01050000500005000050000500005000050000500005000050000",
      "funding_outnum": 1,
      "initial_feerate": "10000perkw",
      "last_feerate": "10000perkw",
      "next_feerate": "10416perkw",
      "inflight": [
        {
          "funding_txid": "channeltxid01050000500005000050000500005000050000500005000050000",
          "funding_outnum": 1,
          "feerate": "10000perkw",
          "total_funding_msat": 20000000,
          "our_funding_msat": 20000000,
          "splice_amount": 0,
          "scratch_txid": "scratchid2030303030303030303030303030303030303030303030303030303"
        }
      ],
      "close_to_addr": "bcrt1pcl00030003000300030003000300030003000300030003000300030003",
      "close_to": "db2dec31030303030303030303030303030303030303030303030303030303030303",
      "private": false,
      "opener": "local",
      "closer": "local",
      "alias": {
        "local": "30000003x60000003x60003",
        "remote": "10000003x20000003x30003"
      },
      "features": [
        "option_static_remotekey",
        "option_anchors"
      ],
      "funding": {
        "local_funds_msat": 20000000,
        "remote_funds_msat": 0,
        "pushed_msat": 0
      },
      "to_us_msat": 20000000,
      "min_to_us_msat": 20000000,
      "max_to_us_msat": 20000000,
      "total_msat": 20000000,
      "fee_base_msat": 1,
      "fee_proportional_millionths": 10,
      "dust_limit_msat": 546000,
      "their_max_htlc_value_in_flight_msat": 18446744073709552000,
      "our_max_htlc_value_in_flight_msat": 18446744073709552000,
      "their_reserve_msat": 546000,
      "our_reserve_msat": 546000,
      "spendable_msat": 8172000,
      "receivable_msat": 0,
      "minimum_htlc_in_msat": 0,
      "minimum_htlc_out_msat": 0,
      "maximum_htlc_out_msat": 19454000,
      "their_to_self_delay": 5,
      "our_to_self_delay": 5,
      "max_accepted_htlcs": 483,
      "state_changes": [
        {
          "timestamp": "2024-10-10T00:01:00.000Z",
          "old_state": "DUALOPEND_OPEN_COMMITTED",
          "new_state": "DUALOPEND_AWAITING_LOCKIN",
          "cause": "user",
          "message": "Sigs exchanged, waiting for lock-in"
        },
        {
          "timestamp": "2024-10-10T00:02:00.000Z",
          "old_state": "DUALOPEND_AWAITING_LOCKIN",
          "new_state": "CHANNELD_SHUTTING_DOWN",
          "cause": "user",
          "message": "User or plugin invoked close command"
        },
        {
          "timestamp": "2024-10-10T00:03:00.000Z",
          "old_state": "CHANNELD_SHUTTING_DOWN",
          "new_state": "CLOSINGD_SIGEXCHANGE",
          "cause": "user",
          "message": "Start closingd"
        },
        {
          "timestamp": "2024-10-10T00:04:00.000Z",
          "old_state": "CLOSINGD_SIGEXCHANGE",
          "new_state": "CLOSINGD_COMPLETE",
          "cause": "user",
          "message": "Closing complete"
        },
        {
          "timestamp": "2024-10-10T00:05:00.000Z",
          "old_state": "CLOSINGD_COMPLETE",
          "new_state": "FUNDING_SPEND_SEEN",
          "cause": "user",
          "message": "Onchain funding spend"
        },
        {
          "timestamp": "2024-10-10T00:06:00.000Z",
          "old_state": "FUNDING_SPEND_SEEN",
          "new_state": "ONCHAIN",
          "cause": "user",
          "message": "Onchain init reply"
        }
      ],
      "status": [
        "CLOSINGD_SIGEXCHANGE:We agreed on a closing fee of 2250 satoshi for tx:scratchid2030303030303030303030303030303030303030303030303030303",
        "ONCHAIN:Tracking mutual close transaction",
        "ONCHAIN:All outputs resolved: waiting 96 more blocks before forgetting channel"
      ],
      "in_payments_offered": 0,
      "in_offered_msat": 0,
      "in_payments_fulfilled": 0,
      "in_fulfilled_msat": 0,
      "out_payments_offered": 0,
      "out_offered_msat": 0,
      "out_payments_fulfilled": 0,
      "out_fulfilled_msat": 0,
      "htlcs": [],
      "last_stable_connection": 1738530000
    }
  ]
}

okay so a few things to clock, bestie πŸ‘€

  • Channel one is "state": "CHANNELD_NORMAL", "peer_connected": true, and it's got the little "reestablished": true badge on it like a friendship bracelet 🫢 Its "status" is literally "CHANNELD_NORMAL:Channel ready for use." β€” thriving.
  • It's also got exactly one HTLC mid-flight in "htlcs", "state": "SENT_ADD_ACK_REVOCATION", "direction": "out", "id": 17, "amount_msat": 4000082, "expiry": 181. Not me refreshing my little payment tracker 😭
  • Channel two is "peer_connected": false, "state": "ONCHAIN", "owner": "onchaind", and it's got both "opener": "local" AND "closer": "local" β€” she opened it, she closed it, she contained multitudes ✨ It also has "closer" at all, plus "initial_feerate", "last_feerate", "next_feerate" and an "inflight" entry, which channel one just… doesn't. Different eras, different fields, no notes.
  • Peep the "state_changes" journey on channel two: DUALOPEND_OPEN_COMMITTED β†’ DUALOPEND_AWAITING_LOCKIN β†’ CHANNELD_SHUTTING_DOWN β†’ CLOSINGD_SIGEXCHANGE β†’ CLOSINGD_COMPLETE β†’ FUNDING_SPEND_SEEN β†’ ONCHAIN. It's giving character development 😌
  • And the last "status" line on it: "ONCHAIN:All outputs resolved: waiting 96 more blocks before forgetting channel" β€” she's not gone, she's just on a 96-block wellness retreat πŸ’…
  • Also "lost_state": false on BOTH, which is the vibe we want. And "htlcs": [] on channel two, because there's nothing left to send, "receivable_msat": 0 bestie.

one tiny thing: "channels" is the key holding the whole array β€” if a channel has no "updates".remote" like channel two, that just means it only printed "local". That's literally what's in the output, don't read anything extra into it πŸ™ˆ

and that's the whole page, bestie! πŸŽ€ happy channel-stalking. this page came to you straight from the Core Lightning girlies β€” version v26.06.9 β€” and it's LIGHTNING-LISTPEERCHANNELS(7) if you ever need to find it again. go check your listpeerchannels output, feel your feelings, slay, periodt πŸ’–πŸ¦‹βœ¨

πŸ“¦ where this page comes from