diff --git a/api/api.go b/api/api.go index 55267b34..2a60ba2c 100644 --- a/api/api.go +++ b/api/api.go @@ -694,7 +694,7 @@ func (api *api) GetBalances(ctx context.Context) (*BalancesResponse, error) { if api.svc.GetLNClient() == nil { return nil, errors.New("LNClient not started") } - balances, err := api.svc.GetLNClient().GetBalances(ctx) + balances, err := api.svc.GetLNClient().GetBalances(ctx, false) if err != nil { return nil, err } diff --git a/lnclient/cashu/cashu.go b/lnclient/cashu/cashu.go index ce9bae71..3f570f0e 100644 --- a/lnclient/cashu/cashu.go +++ b/lnclient/cashu/cashu.go @@ -283,7 +283,7 @@ func (cs *CashuService) UpdateChannel(ctx context.Context, updateChannelRequest return nil } -func (cs *CashuService) GetBalances(ctx context.Context) (*lnclient.BalancesResponse, error) { +func (cs *CashuService) GetBalances(ctx context.Context, includeInactiveChannels bool) (*lnclient.BalancesResponse, error) { cashuBalance := cs.wallet.GetBalance() balance := int64(cashuBalance * 1000) diff --git a/lnclient/ldk/ldk.go b/lnclient/ldk/ldk.go index 82c0a1c4..d5989448 100644 --- a/lnclient/ldk/ldk.go +++ b/lnclient/ldk/ldk.go @@ -1624,7 +1624,7 @@ func (ls *LDKService) saveStaticChannelBackupToDisk(event *events.StaticChannels logger.Logger.WithField("backupPath", backupFilePath).Debug("Saved static channel backup to disk") } -func (ls *LDKService) GetBalances(ctx context.Context) (*lnclient.BalancesResponse, error) { +func (ls *LDKService) GetBalances(ctx context.Context, includeInactiveChannels bool) (*lnclient.BalancesResponse, error) { onchainBalance, err := ls.GetOnchainBalance(ctx) if err != nil { logger.Logger.WithError(err).Error("Failed to retrieve onchain balance") @@ -1639,7 +1639,7 @@ func (ls *LDKService) GetBalances(ctx context.Context) (*lnclient.BalancesRespon var nextMaxSpendableMPP int64 = 0 channels := ls.node.ListChannels() for _, channel := range channels { - if channel.IsUsable { + if channel.IsUsable || includeInactiveChannels { // spending or receiving amount may be constrained by channel configuration (e.g. ACINQ does this) channelConstrainedSpendable := min(int64(channel.OutboundCapacityMsat), int64(*channel.CounterpartyOutboundHtlcMaximumMsat)) channelConstrainedReceivable := min(int64(channel.InboundCapacityMsat), int64(*channel.InboundHtlcMaximumMsat)) diff --git a/lnclient/lnd/lnd.go b/lnclient/lnd/lnd.go index 4c1e8751..77f604c6 100644 --- a/lnclient/lnd/lnd.go +++ b/lnclient/lnd/lnd.go @@ -1083,7 +1083,7 @@ func (svc *LNDService) GetLogOutput(ctx context.Context, maxLen int) ([]byte, er return slicedBytes, nil } -func (svc *LNDService) GetBalances(ctx context.Context) (*lnclient.BalancesResponse, error) { +func (svc *LNDService) GetBalances(ctx context.Context, includeInactiveChannels bool) (*lnclient.BalancesResponse, error) { onchainBalance, err := svc.GetOnchainBalance(ctx) if err != nil { return nil, err @@ -1104,7 +1104,7 @@ func (svc *LNDService) GetBalances(ctx context.Context) (*lnclient.BalancesRespo for _, channel := range resp.Channels { // Unnecessary since ListChannels only returns active channels - if channel.Active { + if channel.Active || includeInactiveChannels { channelSpendable := max(channel.LocalBalance*1000-int64(channel.LocalConstraints.ChanReserveSat*1000), 0) channelReceivable := max(channel.RemoteBalance*1000-int64(channel.RemoteConstraints.ChanReserveSat*1000), 0) diff --git a/lnclient/models.go b/lnclient/models.go index 0cb4b8e5..76d47d4a 100644 --- a/lnclient/models.go +++ b/lnclient/models.go @@ -66,7 +66,7 @@ type LNClient interface { GetNewOnchainAddress(ctx context.Context) (string, error) ResetRouter(key string) error GetOnchainBalance(ctx context.Context) (*OnchainBalanceResponse, error) - GetBalances(ctx context.Context) (*BalancesResponse, error) + GetBalances(ctx context.Context, includeInactiveChannels bool) (*BalancesResponse, error) RedeemOnchainFunds(ctx context.Context, toAddress string, amount uint64, sendAll bool) (txId string, err error) SendPaymentProbes(ctx context.Context, invoice string) error SendSpontaneousPaymentProbes(ctx context.Context, amountMsat uint64, nodeId string) error diff --git a/lnclient/phoenixd/phoenixd.go b/lnclient/phoenixd/phoenixd.go index 77501952..b8f8758b 100644 --- a/lnclient/phoenixd/phoenixd.go +++ b/lnclient/phoenixd/phoenixd.go @@ -92,7 +92,7 @@ func NewPhoenixService(address string, authorization string) (result lnclient.LN return phoenixService, nil } -func (svc *PhoenixService) GetBalances(ctx context.Context) (*lnclient.BalancesResponse, error) { +func (svc *PhoenixService) GetBalances(ctx context.Context, includeInactiveChannels bool) (*lnclient.BalancesResponse, error) { req, err := http.NewRequest(http.MethodGet, svc.Address+"/getbalance", nil) if err != nil { return nil, err diff --git a/nip47/controllers/get_balance_controller.go b/nip47/controllers/get_balance_controller.go index 18d342fd..a75cb288 100644 --- a/nip47/controllers/get_balance_controller.go +++ b/nip47/controllers/get_balance_controller.go @@ -33,7 +33,7 @@ func (controller *nip47Controller) HandleGetBalanceEvent(ctx context.Context, ni if app.Isolated { balance = queries.GetIsolatedBalance(controller.db, app.ID) } else { - balances, err := controller.lnClient.GetBalances(ctx) + balances, err := controller.lnClient.GetBalances(ctx, true) balance = balances.Lightning.TotalSpendable if err != nil { logger.Logger.WithFields(logrus.Fields{ diff --git a/tests/mock_ln_client.go b/tests/mock_ln_client.go index 2d19e6f5..10029f92 100644 --- a/tests/mock_ln_client.go +++ b/tests/mock_ln_client.go @@ -137,7 +137,7 @@ func (mln *MockLn) CloseChannel(ctx context.Context, closeChannelRequest *lnclie func (mln *MockLn) GetNewOnchainAddress(ctx context.Context) (string, error) { return "", nil } -func (mln *MockLn) GetBalances(ctx context.Context) (*lnclient.BalancesResponse, error) { +func (mln *MockLn) GetBalances(ctx context.Context, includeInactiveChannels bool) (*lnclient.BalancesResponse, error) { return &MockLNClientBalances, nil } func (mln *MockLn) GetOnchainBalance(ctx context.Context) (*lnclient.OnchainBalanceResponse, error) { diff --git a/tests/mocks/Config.go b/tests/mocks/Config.go index fe75854a..1a28bf0d 100644 --- a/tests/mocks/Config.go +++ b/tests/mocks/Config.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.52.1. DO NOT EDIT. +// Code generated by mockery v2.53.2. DO NOT EDIT. package mocks diff --git a/tests/mocks/LNClient.go b/tests/mocks/LNClient.go index 67e2a309..23174b25 100644 --- a/tests/mocks/LNClient.go +++ b/tests/mocks/LNClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.52.1. DO NOT EDIT. +// Code generated by mockery v2.53.2. DO NOT EDIT. package mocks @@ -234,9 +234,9 @@ func (_c *MockLNClient_ExecuteCustomNodeCommand_Call) RunAndReturn(run func(cont return _c } -// GetBalances provides a mock function with given fields: ctx -func (_m *MockLNClient) GetBalances(ctx context.Context) (*lnclient.BalancesResponse, error) { - ret := _m.Called(ctx) +// GetBalances provides a mock function with given fields: ctx, includeInactiveChannels +func (_m *MockLNClient) GetBalances(ctx context.Context, includeInactiveChannels bool) (*lnclient.BalancesResponse, error) { + ret := _m.Called(ctx, includeInactiveChannels) if len(ret) == 0 { panic("no return value specified for GetBalances") @@ -244,19 +244,19 @@ func (_m *MockLNClient) GetBalances(ctx context.Context) (*lnclient.BalancesResp var r0 *lnclient.BalancesResponse var r1 error - if rf, ok := ret.Get(0).(func(context.Context) (*lnclient.BalancesResponse, error)); ok { - return rf(ctx) + if rf, ok := ret.Get(0).(func(context.Context, bool) (*lnclient.BalancesResponse, error)); ok { + return rf(ctx, includeInactiveChannels) } - if rf, ok := ret.Get(0).(func(context.Context) *lnclient.BalancesResponse); ok { - r0 = rf(ctx) + if rf, ok := ret.Get(0).(func(context.Context, bool) *lnclient.BalancesResponse); ok { + r0 = rf(ctx, includeInactiveChannels) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*lnclient.BalancesResponse) } } - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) + if rf, ok := ret.Get(1).(func(context.Context, bool) error); ok { + r1 = rf(ctx, includeInactiveChannels) } else { r1 = ret.Error(1) } @@ -271,13 +271,14 @@ type MockLNClient_GetBalances_Call struct { // GetBalances is a helper method to define mock.On call // - ctx context.Context -func (_e *MockLNClient_Expecter) GetBalances(ctx interface{}) *MockLNClient_GetBalances_Call { - return &MockLNClient_GetBalances_Call{Call: _e.mock.On("GetBalances", ctx)} +// - includeInactiveChannels bool +func (_e *MockLNClient_Expecter) GetBalances(ctx interface{}, includeInactiveChannels interface{}) *MockLNClient_GetBalances_Call { + return &MockLNClient_GetBalances_Call{Call: _e.mock.On("GetBalances", ctx, includeInactiveChannels)} } -func (_c *MockLNClient_GetBalances_Call) Run(run func(ctx context.Context)) *MockLNClient_GetBalances_Call { +func (_c *MockLNClient_GetBalances_Call) Run(run func(ctx context.Context, includeInactiveChannels bool)) *MockLNClient_GetBalances_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) + run(args[0].(context.Context), args[1].(bool)) }) return _c } @@ -287,7 +288,7 @@ func (_c *MockLNClient_GetBalances_Call) Return(_a0 *lnclient.BalancesResponse, return _c } -func (_c *MockLNClient_GetBalances_Call) RunAndReturn(run func(context.Context) (*lnclient.BalancesResponse, error)) *MockLNClient_GetBalances_Call { +func (_c *MockLNClient_GetBalances_Call) RunAndReturn(run func(context.Context, bool) (*lnclient.BalancesResponse, error)) *MockLNClient_GetBalances_Call { _c.Call.Return(run) return _c } diff --git a/tests/mocks/Service.go b/tests/mocks/Service.go index 466f5213..9218e6ba 100644 --- a/tests/mocks/Service.go +++ b/tests/mocks/Service.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.52.1. DO NOT EDIT. +// Code generated by mockery v2.53.2. DO NOT EDIT. package mocks