Skip to content

Commit

Permalink
feat: show pending balances from channel closures (LDK) (#602)
Browse files Browse the repository at this point in the history
* feat: show pending balances from channel closures (LDK)

* chore: improve pending balances copy

Co-authored-by: Michael Bumann <hello@michaelbumann.com>

* chore: format

---------

Co-authored-by: Michael Bumann <hello@michaelbumann.com>
  • Loading branch information
rolznz and bumi authored Sep 4, 2024
1 parent b378791 commit 6e78d81
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 8 deletions.
30 changes: 28 additions & 2 deletions frontend/src/screens/channels/Channels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
CopyIcon,
Heart,
Hotel,
HourglassIcon,
InfoIcon,
Unplug,
} from "lucide-react";
Expand Down Expand Up @@ -300,11 +301,15 @@ export default function Channels() {
{new Intl.NumberFormat().format(balances.onchain.spendable)}{" "}
sats
{balances &&
balances.onchain.spendable !== balances.onchain.total && (
(balances.onchain.spendable !== balances.onchain.total ||
balances.onchain.pendingBalancesFromChannelClosures >
0) && (
<p className="text-xs text-muted-foreground animate-pulse">
+
{new Intl.NumberFormat().format(
balances.onchain.total - balances.onchain.spendable
balances.onchain.total -
balances.onchain.spendable +
balances.onchain.pendingBalancesFromChannelClosures
)}{" "}
sats incoming
</p>
Expand Down Expand Up @@ -403,6 +408,27 @@ export default function Channels() {
</Card>
</div>

{balances && balances.onchain.pendingBalancesFromChannelClosures > 0 && (
<Alert>
<HourglassIcon className="h-4 w-4" />
<AlertTitle>Pending Closed Channels</AlertTitle>
<AlertDescription>
You have{" "}
{new Intl.NumberFormat().format(
balances.onchain.pendingBalancesFromChannelClosures
)}{" "}
sats pending from one or more closed channels. Once spendable again
these will become available in your savings balance.{" "}
<ExternalLink
to="https://guides.getalby.com/user-guide/v/alby-account-and-browser-extension/alby-hub/faq-alby-hub/why-was-my-lightning-channel-closed-and-what-to-do-next"
className="underline"
>
Learn more
</ExternalLink>
</AlertDescription>
</Alert>
)}

{channels && channels.length === 0 && (
<EmptyState
icon={Unplug}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ export type OnchainBalanceResponse = {
spendable: number;
total: number;
reserved: number;
pendingBalancesFromChannelClosures: number;
};

// from https://mempool.space/docs/api/rest#get-node-stats
Expand Down
49 changes: 46 additions & 3 deletions lnclient/ldk/ldk.go
Original file line number Diff line number Diff line change
Expand Up @@ -988,14 +988,57 @@ func (ls *LDKService) GetNewOnchainAddress(ctx context.Context) (string, error)
}

func (ls *LDKService) GetOnchainBalance(ctx context.Context) (*lnclient.OnchainBalanceResponse, error) {
channels := ls.node.ListChannels()
balances := ls.node.ListBalances()
logger.Logger.WithFields(logrus.Fields{
"balances": balances,
}).Debug("Listed Balances")

pendingBalancesFromChannelClosures := uint64(0)
// increase pending balance from any lightning balances for channels that are pending closure
// (they do not exist in our list of open channels)
for _, balance := range balances.LightningBalances {
increasePendingBalance := func(channelId string, amount uint64) {
if !slices.ContainsFunc(channels, func(channel ldk_node.ChannelDetails) bool {
return channel.ChannelId == channelId
}) {
pendingBalancesFromChannelClosures += amount
}
}

switch balanceType := (balance).(type) {
case ldk_node.LightningBalanceClaimableOnChannelClose:
increasePendingBalance(balanceType.ChannelId, balanceType.AmountSatoshis)
case ldk_node.LightningBalanceClaimableAwaitingConfirmations:
increasePendingBalance(balanceType.ChannelId, balanceType.AmountSatoshis)
case ldk_node.LightningBalanceContentiousClaimable:
increasePendingBalance(balanceType.ChannelId, balanceType.AmountSatoshis)
case ldk_node.LightningBalanceMaybeTimeoutClaimableHtlc:
increasePendingBalance(balanceType.ChannelId, balanceType.AmountSatoshis)
case ldk_node.LightningBalanceMaybePreimageClaimableHtlc:
increasePendingBalance(balanceType.ChannelId, balanceType.AmountSatoshis)
case ldk_node.LightningBalanceCounterpartyRevokedOutputClaimable:
increasePendingBalance(balanceType.ChannelId, balanceType.AmountSatoshis)
}
}

// increase pending balance from any lightning balances for channels that were closed
for _, balance := range balances.PendingBalancesFromChannelClosures {
switch pendingType := (balance).(type) {
case ldk_node.PendingSweepBalancePendingBroadcast:
pendingBalancesFromChannelClosures += pendingType.AmountSatoshis
case ldk_node.PendingSweepBalanceBroadcastAwaitingConfirmation:
pendingBalancesFromChannelClosures += pendingType.AmountSatoshis
case ldk_node.PendingSweepBalanceAwaitingThresholdConfirmations:
pendingBalancesFromChannelClosures += pendingType.AmountSatoshis
}
}

return &lnclient.OnchainBalanceResponse{
Spendable: int64(balances.SpendableOnchainBalanceSats),
Total: int64(balances.TotalOnchainBalanceSats - balances.TotalAnchorChannelsReserveSats),
Reserved: int64(balances.TotalAnchorChannelsReserveSats),
Spendable: int64(balances.SpendableOnchainBalanceSats),
Total: int64(balances.TotalOnchainBalanceSats - balances.TotalAnchorChannelsReserveSats),
Reserved: int64(balances.TotalAnchorChannelsReserveSats),
PendingBalancesFromChannelClosures: pendingBalancesFromChannelClosures,
}, nil
}

Expand Down
7 changes: 4 additions & 3 deletions lnclient/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,10 @@ type CloseChannelResponse struct {
}

type OnchainBalanceResponse struct {
Spendable int64 `json:"spendable"`
Total int64 `json:"total"`
Reserved int64 `json:"reserved"`
Spendable int64 `json:"spendable"`
Total int64 `json:"total"`
Reserved int64 `json:"reserved"`
PendingBalancesFromChannelClosures uint64 `json:"pendingBalancesFromChannelClosures"`
}

type PeerDetails struct {
Expand Down

0 comments on commit 6e78d81

Please sign in to comment.