Problem
When you open a channel you can attach a memo — a private note-to-self, stored only on your own node, that has no effect on the channel itself. It's set once via OpenChannel/BatchOpenChannel (and lncli openchannel --memo) and shown back in ListChannels and PendingChannels.
The gap: once the channel exists — whether pending (funding transaction broadcast but not yet confirmed) or fully open — there is no way to change that note. If you made a typo, or your reason for the channel changed, or you just want to add context later, you're stuck with whatever you typed at open time. The only channel-editing RPC today is UpdateChannelPolicy, and that only touches forwarding fees/timelock — not the memo.
Because the memo is local metadata that has zero impact on channel operation or the network, letting the operator edit it later is low-risk.
Where things stand today
- Set at open only:
OpenChannelRequest.memo (field 27), BatchOpenChannel.memo (field 20), and lncli openchannel --memo.
- Read back in:
Channel.memo (ListChannels) and PendingChannel.memo (PendingChannels).
- Stored locally as a TLV record (type 5) on the open-channel record in the channel DB (
chanstate/kv_open_channel.go), and never rewritten after creation.
- First written to disk when the channel reservation completes: the pending channel record (memo included) is saved via
OpenChannel.SyncPending (lnwallet/wallet.go:2384), right after the funding transaction is finalized. That is the same moment the funding outpoint (channel point) is fixed and the channel starts appearing in PendingChannels. Before that, during funding negotiation, the memo lives only in memory: rpcserver.go:2486 → the funding manager (funding/manager.go) → the reservation's partial state (lnwallet/reservation.go:521).
- A 500-character limit is enforced at open time (
rpcserver.go:2443).
Proposed change
Add a small RPC that sets the memo on an existing channel, identified by its channel point. Setting an empty string clears the memo. Reuse the same 500-character limit as openchannel.
Which channels this covers. Because the channel is identified by its channel point (the funding outpoint), this works on any channel that has a stored memo — both pending-open channels (funding transaction broadcast but not yet confirmed) and fully open channels. Pending channels already carry a channel point and keep the memo in the same open-channel record, so they need no extra handling.
There is no earlier case to worry about. During funding negotiation, before a funding outpoint exists, the memo passed to OpenChannel lives only in memory and has not been written to the channel DB yet — that first write happens when the reservation completes and SyncPending saves the pending channel (lnwallet/wallet.go:2384), which is also when the channel point is fixed. At that stage the channel appears in neither ListChannels nor PendingChannels — both read from the channel DB, and there is no record yet (ListChannels in particular only reports channels with a confirmed funding transaction). So at that stage there is nothing stored to edit and no stable ID to point at. In short: every channel that has a memo on disk has a channel point, so every stored memo is editable.
RPC sketch (lnrpc/lightning.proto)
service Lightning {
// ... existing methods ...
/*
UpdateChannelMemo sets or replaces the local memo (a private
note-to-self) on an existing channel. The memo is stored only on this
node and does not affect the channel's operation.
*/
rpc UpdateChannelMemo (UpdateChannelMemoRequest)
returns (UpdateChannelMemoResponse);
}
message UpdateChannelMemoRequest {
// The channel whose memo should be updated.
ChannelPoint chan_point = 1;
// The new memo text. Replaces any existing memo. Max 500 characters.
// An empty string clears the memo.
string memo = 2;
}
message UpdateChannelMemoResponse {
}
Supporting changes
- rpcserver.go: add the
UpdateChannelMemo handler — validate the 500-char limit (reuse the existing check), resolve chan_point to the channel, and call a new store method to persist the memo. Return an error if the channel isn't found.
- chanstate (channel store): add a method such as
UpdateMemo(chanPoint wire.OutPoint, memo []byte) error on the open-channel store that rewrites just the memo TLV record for that channel, plus an in-memory setter on OpenChannel. This mirrors how other single-field updates on an open channel already work (e.g. the existing Mark*/Set* helpers).
- lncli: add a command, e.g.
lncli updatechanmemo --chan_point <txid:index> --memo "<text>".
- docs / release notes: note the new RPC and command.
Open questions
- Command/RPC naming:
UpdateChannelMemo vs. folding it into an existing update command.
- Any macaroon/permission entry — likely the same write permission as other channel-modifying calls.
Problem
When you open a channel you can attach a
memo— a private note-to-self, stored only on your own node, that has no effect on the channel itself. It's set once viaOpenChannel/BatchOpenChannel(andlncli openchannel --memo) and shown back inListChannelsandPendingChannels.The gap: once the channel exists — whether pending (funding transaction broadcast but not yet confirmed) or fully open — there is no way to change that note. If you made a typo, or your reason for the channel changed, or you just want to add context later, you're stuck with whatever you typed at open time. The only channel-editing RPC today is
UpdateChannelPolicy, and that only touches forwarding fees/timelock — not the memo.Because the memo is local metadata that has zero impact on channel operation or the network, letting the operator edit it later is low-risk.
Where things stand today
OpenChannelRequest.memo(field 27),BatchOpenChannel.memo(field 20), andlncli openchannel --memo.Channel.memo(ListChannels) andPendingChannel.memo(PendingChannels).chanstate/kv_open_channel.go), and never rewritten after creation.OpenChannel.SyncPending(lnwallet/wallet.go:2384), right after the funding transaction is finalized. That is the same moment the funding outpoint (channel point) is fixed and the channel starts appearing inPendingChannels. Before that, during funding negotiation, the memo lives only in memory:rpcserver.go:2486→ the funding manager (funding/manager.go) → the reservation's partial state (lnwallet/reservation.go:521).rpcserver.go:2443).Proposed change
Add a small RPC that sets the memo on an existing channel, identified by its channel point. Setting an empty string clears the memo. Reuse the same 500-character limit as
openchannel.Which channels this covers. Because the channel is identified by its channel point (the funding outpoint), this works on any channel that has a stored memo — both pending-open channels (funding transaction broadcast but not yet confirmed) and fully open channels. Pending channels already carry a channel point and keep the memo in the same open-channel record, so they need no extra handling.
There is no earlier case to worry about. During funding negotiation, before a funding outpoint exists, the memo passed to
OpenChannellives only in memory and has not been written to the channel DB yet — that first write happens when the reservation completes andSyncPendingsaves the pending channel (lnwallet/wallet.go:2384), which is also when the channel point is fixed. At that stage the channel appears in neitherListChannelsnorPendingChannels— both read from the channel DB, and there is no record yet (ListChannelsin particular only reports channels with a confirmed funding transaction). So at that stage there is nothing stored to edit and no stable ID to point at. In short: every channel that has a memo on disk has a channel point, so every stored memo is editable.RPC sketch (lnrpc/lightning.proto)
Supporting changes
UpdateChannelMemohandler — validate the 500-char limit (reuse the existing check), resolvechan_pointto the channel, and call a new store method to persist the memo. Return an error if the channel isn't found.UpdateMemo(chanPoint wire.OutPoint, memo []byte) erroron the open-channel store that rewrites just the memo TLV record for that channel, plus an in-memory setter onOpenChannel. This mirrors how other single-field updates on an open channel already work (e.g. the existingMark*/Set*helpers).lncli updatechanmemo --chan_point <txid:index> --memo "<text>".Open questions
UpdateChannelMemovs. folding it into an existing update command.