diff --git a/alby/alby_oauth_service.go b/alby/alby_oauth_service.go index e0bed1be..7c264d9b 100644 --- a/alby/alby_oauth_service.go +++ b/alby/alby_oauth_service.go @@ -525,7 +525,7 @@ func (svc *albyOAuthService) UnlinkAccount(ctx context.Context) error { return nil } -func (svc *albyOAuthService) LinkAccount(ctx context.Context, lnClient lnclient.LNClient, budget uint64, renewal string) error { +func (svc *albyOAuthService) LinkAccount(ctx context.Context, lnClient lnclient.LNClient, budgetSat uint64, renewal string) error { if lnClient == nil { return errors.New("LNClient not available") } @@ -551,7 +551,7 @@ func (svc *albyOAuthService) LinkAccount(ctx context.Context, lnClient lnclient. app, _, err := apps.NewAppsService(svc.db, svc.eventPublisher, svc.keys, svc.cfg).CreateApp( ALBY_ACCOUNT_APP_NAME, connectionPubkey, - budget, + budgetSat, renewal, nil, scopes, @@ -1325,11 +1325,11 @@ func (svc *albyOAuthService) requestAutoChannel(ctx context.Context, url string, } var invoice string - var fee uint64 + var feeSat uint64 if newAutoChannelResponse.Payment != nil { invoice = newAutoChannelResponse.Payment.Bolt11.Invoice - fee, err = strconv.ParseUint(newAutoChannelResponse.Payment.Bolt11.FeeTotalSat, 10, 64) + feeSat, err = strconv.ParseUint(newAutoChannelResponse.Payment.Bolt11.FeeTotalSat, 10, 64) if err != nil { logger.Logger.WithError(err).WithFields(logrus.Fields{ "url": url, @@ -1343,16 +1343,16 @@ func (svc *albyOAuthService) requestAutoChannel(ctx context.Context, url string, return nil, err } - if fee != uint64(paymentRequest.MSatoshi/1000) { + if feeSat != uint64(paymentRequest.MSatoshi/1000) { logger.Logger.WithFields(logrus.Fields{ "invoice_amount": paymentRequest.MSatoshi / 1000, - "fee": fee, + "fee": feeSat, }).WithError(err).Error("Invoice amount does not match LSP fee") return nil, errors.New("invoice amount does not match LSP fee") } } - channelSize, err := strconv.ParseUint(newAutoChannelResponse.LspBalanceSat, 10, 64) + channelSizeSat, err := strconv.ParseUint(newAutoChannelResponse.LspBalanceSat, 10, 64) if err != nil { logger.Logger.WithError(err).WithFields(logrus.Fields{ "url": url, @@ -1361,9 +1361,11 @@ func (svc *albyOAuthService) requestAutoChannel(ctx context.Context, url string, } return &AutoChannelResponse{ - Invoice: invoice, - Fee: fee, - ChannelSize: channelSize, + Invoice: invoice, + Fee: feeSat, + FeeSat: feeSat, + ChannelSize: channelSizeSat, + ChannelSizeSat: channelSizeSat, }, nil } diff --git a/alby/alby_service.go b/alby/alby_service.go index b4bd3077..6514350d 100644 --- a/alby/alby_service.go +++ b/alby/alby_service.go @@ -170,6 +170,11 @@ func (svc *albyService) GetChannelPeerSuggestions(ctx context.Context) ([]Channe return nil, err } + for i := range suggestions { + suggestions[i].MinimumChannelSizeSat = suggestions[i].MinimumChannelSize + suggestions[i].MaximumChannelSizeSat = suggestions[i].MaximumChannelSize + } + logger.Logger.WithFields(logrus.Fields{"channel_suggestions": suggestions}).Debug("Alby channel peer suggestions response") return suggestions, nil } diff --git a/alby/models.go b/alby/models.go index 3d4854d9..2fe5e6b3 100644 --- a/alby/models.go +++ b/alby/models.go @@ -23,7 +23,7 @@ type AlbyOAuthService interface { GetUserIdentifier() (string, error) GetLightningAddress() (string, error) IsConnected(ctx context.Context) bool - LinkAccount(ctx context.Context, lnClient lnclient.LNClient, budget uint64, renewal string) error + LinkAccount(ctx context.Context, lnClient lnclient.LNClient, budgetSat uint64, renewal string) error CallbackHandler(ctx context.Context, code string) error GetMe(ctx context.Context) (*AlbyMe, error) UnlinkAccount(ctx context.Context) error @@ -49,9 +49,11 @@ type AutoChannelRequest struct { } type AutoChannelResponse struct { - Invoice string `json:"invoice"` - ChannelSize uint64 `json:"channelSize"` - Fee uint64 `json:"fee"` + Invoice string `json:"invoice"` + ChannelSize uint64 `json:"channelSize"` // deprecated + ChannelSizeSat uint64 `json:"channelSizeSat"` + Fee uint64 `json:"fee"` // deprecated + FeeSat uint64 `json:"feeSat"` } type AlbyInfoHub struct { @@ -102,8 +104,10 @@ type ChannelPeerSuggestion struct { PaymentMethod string `json:"paymentMethod"` Pubkey string `json:"pubkey"` Host string `json:"host"` - MinimumChannelSize uint64 `json:"minimumChannelSize"` - MaximumChannelSize uint64 `json:"maximumChannelSize"` + MinimumChannelSize uint64 `json:"minimumChannelSize"` // deprecated + MinimumChannelSizeSat uint64 `json:"minimumChannelSizeSat"` + MaximumChannelSize uint64 `json:"maximumChannelSize"` // deprecated + MaximumChannelSizeSat uint64 `json:"maximumChannelSizeSat"` MaximumChannelExpiryBlocks *uint32 `json:"maximumChannelExpiryBlocks"` Name string `json:"name"` Image string `json:"image"` diff --git a/api/api.go b/api/api.go index 4e31bed3..e13b216a 100644 --- a/api/api.go +++ b/api/api.go @@ -210,7 +210,7 @@ func (api *api) UpdateApp(userApp *db.App, updateAppRequest *UpdateAppRequest) e updateAppRequest.BudgetRenewal != nil || updateAppRequest.ExpiresAt != nil || updateAppRequest.UpdateExpiresAt { // Get current values or use provided ones - var maxAmount uint64 + var maxAmountSat uint64 var budgetRenewal string var expiresAt *time.Time @@ -225,7 +225,7 @@ func (api *api) UpdateApp(userApp *db.App, updateAppRequest *UpdateAppRequest) e // Find pay_invoice permission for budget-related fields for _, perm := range existingPermissions { if perm.Scope == constants.PAY_INVOICE_SCOPE { - maxAmount = uint64(perm.MaxAmountSat) + maxAmountSat = uint64(perm.MaxAmountSat) budgetRenewal = perm.BudgetRenewal expiresAt = perm.ExpiresAt break @@ -235,7 +235,7 @@ func (api *api) UpdateApp(userApp *db.App, updateAppRequest *UpdateAppRequest) e // Override with provided values if updateAppRequest.MaxAmountSat != nil { - maxAmount = *updateAppRequest.MaxAmountSat + maxAmountSat = *updateAppRequest.MaxAmountSat } if updateAppRequest.BudgetRenewal != nil { budgetRenewal = *updateAppRequest.BudgetRenewal @@ -254,7 +254,7 @@ func (api *api) UpdateApp(userApp *db.App, updateAppRequest *UpdateAppRequest) e // Update existing permissions with new budget and expiry err := tx.Model(&db.AppPermission{}).Where("app_id", userApp.ID).Updates(map[string]interface{}{ "ExpiresAt": expiresAt, - "MaxAmountSat": maxAmount, + "MaxAmountSat": maxAmountSat, "BudgetRenewal": budgetRenewal, }).Error if err != nil { @@ -284,7 +284,7 @@ func (api *api) UpdateApp(userApp *db.App, updateAppRequest *UpdateAppRequest) e App: *userApp, Scope: scope, ExpiresAt: expiresAt, - MaxAmountSat: int(maxAmount), + MaxAmountSat: int(maxAmountSat), BudgetRenewal: budgetRenewal, } if err := tx.Create(&perm).Error; err != nil { @@ -429,8 +429,8 @@ func (api *api) GetApp(dbApp *db.App) (*App, error) { } // renewsIn := "" - maxAmount := uint64(paySpecificPermission.MaxAmountSat) - budgetUsage, err := queries.GetBudgetUsage(api.db, &paySpecificPermission) + maxAmountSat := uint64(paySpecificPermission.MaxAmountSat) + budgetUsageMsat, err := queries.GetBudgetUsageMsat(api.db, &paySpecificPermission) if err != nil { logger.Logger.WithError(err).WithFields(logrus.Fields{ "app_id": dbApp.ID, @@ -463,9 +463,13 @@ func (api *api) GetApp(dbApp *db.App) (*App, error) { UpdatedAt: dbApp.UpdatedAt, AppPubkey: dbApp.AppPubkey, ExpiresAt: expiresAt, - MaxAmountSat: maxAmount, + MaxAmount: maxAmountSat, + MaxAmountSat: maxAmountSat, + MaxAmountMsat: maxAmountSat * 1000, Scopes: requestMethods, - BudgetUsage: budgetUsage / 1000, + BudgetUsage: budgetUsageMsat / 1000, + BudgetUsageSat: budgetUsageMsat / 1000, + BudgetUsageMsat: budgetUsageMsat, BudgetRenewal: paySpecificPermission.BudgetRenewal, Isolated: dbApp.Isolated, Metadata: metadata, @@ -476,14 +480,16 @@ func (api *api) GetApp(dbApp *db.App) (*App, error) { } if dbApp.Isolated { - balance, err := queries.GetIsolatedBalance(api.db, dbApp.ID) + balanceMsat, err := queries.GetIsolatedBalanceMsat(api.db, dbApp.ID) if err != nil { logger.Logger.WithError(err).WithFields(logrus.Fields{ "app_id": dbApp.ID, }).Error("Failed to get isolated app balance") return nil, err } - response.Balance = balance + response.Balance = balanceMsat + response.BalanceSat = balanceMsat / 1000 + response.BalanceMsat = balanceMsat } return &response, nil @@ -539,13 +545,16 @@ func (api *api) ListApps(limit uint64, offset uint64, filters ListAppsFilters, o } var totalBalance *int64 + var totalBalanceSat *int64 if filters.SubWallets != nil && *filters.SubWallets { - totalBalanceMsat, err := queries.GetTotalSubwalletBalance(api.db) + totalBalanceMsat, err := queries.GetTotalSubwalletBalanceMsat(api.db) if err != nil { logger.Logger.WithError(err).Error("Failed to calculate total subwallet balance") return nil, err } totalBalance = &totalBalanceMsat + totalBalanceSatVal := totalBalanceMsat / 1000 + totalBalanceSat = &totalBalanceSatVal } query = query.Offset(int(offset)).Limit(int(limit)) @@ -597,14 +606,16 @@ func (api *api) ListApps(limit uint64, offset uint64, filters ListAppsFilters, o } if dbApp.Isolated { - balance, err := queries.GetIsolatedBalance(api.db, dbApp.ID) + balanceMsat, err := queries.GetIsolatedBalanceMsat(api.db, dbApp.ID) if err != nil { logger.Logger.WithError(err).WithFields(logrus.Fields{ "app_id": dbApp.ID, }).Error("Failed to get isolated app balance") return nil, err } - apiApp.Balance = balance + apiApp.Balance = balanceMsat + apiApp.BalanceSat = balanceMsat / 1000 + apiApp.BalanceMsat = balanceMsat } for _, appPermission := range permissionsMap[dbApp.ID] { @@ -612,15 +623,19 @@ func (api *api) ListApps(limit uint64, offset uint64, filters ListAppsFilters, o apiApp.ExpiresAt = appPermission.ExpiresAt if appPermission.Scope == constants.PAY_INVOICE_SCOPE { apiApp.BudgetRenewal = appPermission.BudgetRenewal + apiApp.MaxAmount = uint64(appPermission.MaxAmountSat) apiApp.MaxAmountSat = uint64(appPermission.MaxAmountSat) - budgetUsage, err := queries.GetBudgetUsage(api.db, &appPermission) + apiApp.MaxAmountMsat = uint64(appPermission.MaxAmountSat) * 1000 + budgetUsageMsat, err := queries.GetBudgetUsageMsat(api.db, &appPermission) if err != nil { logger.Logger.WithError(err).WithFields(logrus.Fields{ "app_id": dbApp.ID, }).Error("Failed to get budget usage for app") return nil, err } - apiApp.BudgetUsage = budgetUsage / 1000 + apiApp.BudgetUsage = budgetUsageMsat / 1000 + apiApp.BudgetUsageSat = budgetUsageMsat / 1000 + apiApp.BudgetUsageMsat = budgetUsageMsat } } @@ -638,9 +653,11 @@ func (api *api) ListApps(limit uint64, offset uint64, filters ListAppsFilters, o apiApps = append(apiApps, apiApp) } return &ListAppsResponse{ - Apps: apiApps, - TotalCount: uint64(totalCount), - TotalBalance: totalBalance, + Apps: apiApps, + TotalCount: uint64(totalCount), + TotalBalance: totalBalance, + TotalBalanceSat: totalBalanceSat, + TotalBalanceMsat: totalBalance, }, nil } @@ -676,8 +693,14 @@ func (api *api) ListChannels(ctx context.Context) ([]Channel, error) { apiChannels = append(apiChannels, Channel{ LocalBalance: channel.LocalBalance, + LocalBalanceSat: channel.LocalBalance / 1000, + LocalBalanceMsat: channel.LocalBalance, LocalSpendableBalance: channel.LocalSpendableBalance, + LocalSpendableBalanceSat: channel.LocalSpendableBalance / 1000, + LocalSpendableBalanceMsat: channel.LocalSpendableBalance, RemoteBalance: channel.RemoteBalance, + RemoteBalanceSat: channel.RemoteBalance / 1000, + RemoteBalanceMsat: channel.RemoteBalance, Id: channel.Id, RemotePubkey: channel.RemotePubkey, FundingTxId: channel.FundingTxId, @@ -690,10 +713,12 @@ func (api *api) ListChannels(ctx context.Context) ([]Channel, error) { ForwardingFeeBaseMsat: channel.ForwardingFeeBaseMsat, ForwardingFeeProportionalMillionths: channel.ForwardingFeeProportionalMillionths, UnspendablePunishmentReserve: channel.UnspendablePunishmentReserve, + UnspendablePunishmentReserveSat: channel.UnspendablePunishmentReserve, CounterpartyUnspendablePunishmentReserve: channel.CounterpartyUnspendablePunishmentReserve, - Error: channel.Error, - IsOutbound: channel.IsOutbound, - Status: status, + CounterpartyUnspendablePunishmentReserveSat: channel.CounterpartyUnspendablePunishmentReserve, + Error: channel.Error, + IsOutbound: channel.IsOutbound, + Status: status, }) } @@ -828,23 +853,25 @@ func (api *api) GetAutoSwapConfig() (*GetAutoSwapConfigResponse, error) { } swapOutEnabled := swapOutBalanceThresholdStr != "" && swapOutAmountStr != "" - var swapOutBalanceThreshold, swapOutAmount uint64 + var swapOutBalanceThresholdSat, swapOutAmountSat uint64 if swapOutEnabled { var err error - if swapOutBalanceThreshold, err = strconv.ParseUint(swapOutBalanceThresholdStr, 10, 64); err != nil { + if swapOutBalanceThresholdSat, err = strconv.ParseUint(swapOutBalanceThresholdStr, 10, 64); err != nil { return nil, fmt.Errorf("invalid autoswap out balance threshold: %w", err) } - if swapOutAmount, err = strconv.ParseUint(swapOutAmountStr, 10, 64); err != nil { + if swapOutAmountSat, err = strconv.ParseUint(swapOutAmountStr, 10, 64); err != nil { return nil, fmt.Errorf("invalid autoswap out amount: %w", err) } } return &GetAutoSwapConfigResponse{ - Type: constants.SWAP_TYPE_OUT, - Enabled: swapOutEnabled, - BalanceThreshold: swapOutBalanceThreshold, - SwapAmount: swapOutAmount, - Destination: swapOutDestination, + Type: constants.SWAP_TYPE_OUT, + Enabled: swapOutEnabled, + BalanceThreshold: swapOutBalanceThresholdSat, + BalanceThresholdSat: swapOutBalanceThresholdSat, + SwapAmount: swapOutAmountSat, + SwapAmountSat: swapOutAmountSat, + Destination: swapOutDestination, }, nil } @@ -887,7 +914,9 @@ func toApiSwap(swap *swaps.Swap) *Swap { State: swap.State, Invoice: swap.Invoice, SendAmount: swap.SendAmount, + SendAmountSat: swap.SendAmount, ReceiveAmount: swap.ReceiveAmount, + ReceiveAmountSat: swap.ReceiveAmount, PaymentHash: swap.PaymentHash, DestinationAddress: swap.DestinationAddress, RefundAddress: swap.RefundAddress, @@ -913,11 +942,14 @@ func (api *api) GetSwapInInfo() (*SwapInfoResponse, error) { } return &SwapInfoResponse{ - AlbyServiceFee: swapInInfo.AlbyServiceFee, - BoltzServiceFee: swapInInfo.BoltzServiceFee, - BoltzNetworkFee: swapInInfo.BoltzNetworkFee, - MinAmount: swapInInfo.MinAmount, - MaxAmount: swapInInfo.MaxAmount, + AlbyServiceFee: swapInInfo.AlbyServiceFee, + BoltzServiceFee: swapInInfo.BoltzServiceFee, + BoltzNetworkFee: swapInInfo.BoltzNetworkFee, + BoltzNetworkFeeSat: swapInInfo.BoltzNetworkFee, + MinAmount: swapInInfo.MinAmount, + MinAmountSat: swapInInfo.MinAmount, + MaxAmount: swapInInfo.MaxAmount, + MaxAmountSat: swapInInfo.MaxAmount, }, nil } @@ -932,11 +964,14 @@ func (api *api) GetSwapOutInfo() (*SwapInfoResponse, error) { } return &SwapInfoResponse{ - AlbyServiceFee: swapOutInfo.AlbyServiceFee, - BoltzServiceFee: swapOutInfo.BoltzServiceFee, - BoltzNetworkFee: swapOutInfo.BoltzNetworkFee, - MinAmount: swapOutInfo.MinAmount, - MaxAmount: swapOutInfo.MaxAmount, + AlbyServiceFee: swapOutInfo.AlbyServiceFee, + BoltzServiceFee: swapOutInfo.BoltzServiceFee, + BoltzNetworkFee: swapOutInfo.BoltzNetworkFee, + BoltzNetworkFeeSat: swapOutInfo.BoltzNetworkFee, + MinAmount: swapOutInfo.MinAmount, + MinAmountSat: swapOutInfo.MinAmount, + MaxAmount: swapOutInfo.MaxAmount, + MaxAmountSat: swapOutInfo.MaxAmount, }, nil } @@ -1218,12 +1253,12 @@ func (api *api) SignMessage(ctx context.Context, message string) (*SignMessageRe }, nil } -func (api *api) RedeemOnchainFunds(ctx context.Context, toAddress string, amount uint64, feeRate *uint64, sendAll bool) (*RedeemOnchainFundsResponse, error) { +func (api *api) RedeemOnchainFunds(ctx context.Context, toAddress string, amountSat uint64, feeRate *uint64, sendAll bool) (*RedeemOnchainFundsResponse, error) { lnClient := api.svc.GetLNClient() if lnClient == nil { return nil, ErrLNClientNotStarted } - txId, err := lnClient.RedeemOnchainFunds(ctx, toAddress, amount, feeRate, sendAll) + txId, err := lnClient.RedeemOnchainFunds(ctx, toAddress, amountSat, feeRate, sendAll) if err != nil { return nil, err } @@ -1888,19 +1923,21 @@ func (api *api) GetForwards() (*GetForwardsResponse, error) { return nil, err } - var totalOutboundAmount uint64 - var totalFeeEarned uint64 + var totalOutboundAmountMsat uint64 + var totalFeeEarnedMsat uint64 for _, forward := range forwards { - totalOutboundAmount += forward.OutboundAmountForwardedMsat - totalFeeEarned += forward.TotalFeeEarnedMsat + totalOutboundAmountMsat += forward.OutboundAmountForwardedMsat + totalFeeEarnedMsat += forward.TotalFeeEarnedMsat } numForwards := len(forwards) return &GetForwardsResponse{ - OutboundAmountForwardedMsat: totalOutboundAmount, - TotalFeeEarnedMsat: totalFeeEarned, + OutboundAmountForwardedSat: totalOutboundAmountMsat / 1000, + OutboundAmountForwardedMsat: totalOutboundAmountMsat, + TotalFeeEarnedSat: totalFeeEarnedMsat / 1000, + TotalFeeEarnedMsat: totalFeeEarnedMsat, NumForwards: uint64(numForwards), }, nil } diff --git a/api/lsp.go b/api/lsp.go index 645e742f..3cbbada9 100644 --- a/api/lsp.go +++ b/api/lsp.go @@ -57,9 +57,9 @@ func (api *api) RequestLSPOrder(ctx context.Context, request *LSPOrderRequest) ( return nil, err } - invoice, fee, err := api.requestLSPS1Invoice(ctx, lnClient, request, nodeInfo.Network, nodeInfo.Pubkey, lspInfo.MaxChannelExpiryBlocks, lspInfo.MinRequiredChannelConfirmations, lspInfo.MinFundingConfirmsWithinBlocks) - invoiceAmount := uint64(0) - incomingLiquidity := request.Amount + invoice, feeSat, err := api.requestLSPS1Invoice(ctx, lnClient, request, nodeInfo.Network, nodeInfo.Pubkey, lspInfo.MaxChannelExpiryBlocks, lspInfo.MinRequiredChannelConfirmations, lspInfo.MinFundingConfirmsWithinBlocks) + invoiceAmountSat := uint64(0) + incomingLiquiditySat := request.Amount if err != nil { logger.Logger.WithError(err).Error("Failed to request invoice") @@ -73,15 +73,19 @@ func (api *api) RequestLSPOrder(ctx context.Context, request *LSPOrderRequest) ( return nil, err } - invoiceAmount = uint64(paymentRequest.MSatoshi / 1000) + invoiceAmountSat = uint64(paymentRequest.MSatoshi / 1000) } newChannelResponse := &LSPOrderResponse{ - Invoice: invoice, - Fee: fee, - InvoiceAmount: invoiceAmount, - IncomingLiquidity: incomingLiquidity, - OutgoingLiquidity: uint64(0), // JIT channel no longer supported + Invoice: invoice, + Fee: feeSat, + FeeSat: feeSat, + InvoiceAmount: invoiceAmountSat, + InvoiceAmountSat: invoiceAmountSat, + IncomingLiquidity: incomingLiquiditySat, + IncomingLiquiditySat: incomingLiquiditySat, + OutgoingLiquidity: uint64(0), + OutgoingLiquiditySat: uint64(0), } logger.Logger.WithFields(logrus.Fields{ @@ -91,7 +95,7 @@ func (api *api) RequestLSPOrder(ctx context.Context, request *LSPOrderRequest) ( return newChannelResponse, nil } -func (api *api) requestLSPS1Invoice(ctx context.Context, lnClient lnclient.LNClient, request *LSPOrderRequest, network, pubkey string, channelExpiryBlocks uint64, minRequiredChannelConfirmations uint64, minFundingConfirmsWithinBlocks uint64) (invoice string, fee uint64, err error) { +func (api *api) requestLSPS1Invoice(ctx context.Context, lnClient lnclient.LNClient, request *LSPOrderRequest, network, pubkey string, channelExpiryBlocks uint64, minRequiredChannelConfirmations uint64, minFundingConfirmsWithinBlocks uint64) (invoice string, feeSat uint64, err error) { refundAddress, err := lnClient.GetNewOnchainAddress(ctx) if err != nil { logger.Logger.WithError(err).Error("Failed to request onchain address") @@ -155,7 +159,7 @@ func (api *api) requestLSPS1Invoice(ctx context.Context, lnClient lnclient.LNCli if channelResponse.Payment != nil { invoice = channelResponse.Payment.Bolt11.Invoice - fee, err = strconv.ParseUint(channelResponse.Payment.Bolt11.FeeTotalSat, 10, 64) + feeSat, err = strconv.ParseUint(channelResponse.Payment.Bolt11.FeeTotalSat, 10, 64) if err != nil { logger.Logger.WithError(err).WithFields(logrus.Fields{ "lspIdentifier": request.LSPIdentifier, @@ -164,5 +168,5 @@ func (api *api) requestLSPS1Invoice(ctx context.Context, lnClient lnclient.LNCli } } - return invoice, fee, nil + return invoice, feeSat, nil } diff --git a/api/models.go b/api/models.go index 1adabd7a..b4ce1a9f 100644 --- a/api/models.go +++ b/api/models.go @@ -41,12 +41,12 @@ type API interface { GetNewOnchainAddress(ctx context.Context) (string, error) GetUnusedOnchainAddress(ctx context.Context) (string, error) SignMessage(ctx context.Context, message string) (*SignMessageResponse, error) - RedeemOnchainFunds(ctx context.Context, toAddress string, amount uint64, feeRate *uint64, sendAll bool) (*RedeemOnchainFundsResponse, error) + RedeemOnchainFunds(ctx context.Context, toAddress string, amountSat uint64, feeRate *uint64, sendAll bool) (*RedeemOnchainFundsResponse, error) GetBalances(ctx context.Context) (*BalancesResponse, error) ListTransactions(ctx context.Context, appId *uint, limit uint64, offset uint64) (*ListTransactionsResponse, error) ListOnchainTransactions(ctx context.Context) ([]lnclient.OnchainTransaction, error) SendPayment(ctx context.Context, invoice string, amountMsat *uint64, metadata map[string]interface{}) (*SendPaymentResponse, error) - CreateInvoice(ctx context.Context, amount uint64, description string) (*MakeInvoiceResponse, error) + CreateInvoice(ctx context.Context, amountMsat uint64, description string) (*MakeInvoiceResponse, error) LookupInvoice(ctx context.Context, paymentHash string) (*LookupInvoiceResponse, error) RequestMempoolApi(ctx context.Context, endpoint string) (interface{}, error) GetInfo(ctx context.Context) (*InfoResponse, error) @@ -99,13 +99,19 @@ type App struct { LastSettledTransactionAt *time.Time `json:"lastSettledTransactionAt"` ExpiresAt *time.Time `json:"expiresAt"` Scopes []string `json:"scopes"` - MaxAmountSat uint64 `json:"maxAmount"` - BudgetUsage uint64 `json:"budgetUsage"` + MaxAmount uint64 `json:"maxAmount"` // deprecated + MaxAmountSat uint64 `json:"maxAmountSat"` + MaxAmountMsat uint64 `json:"maxAmountMsat"` + BudgetUsage uint64 `json:"budgetUsage"` // deprecated + BudgetUsageSat uint64 `json:"budgetUsageSat"` + BudgetUsageMsat uint64 `json:"budgetUsageMsat"` BudgetRenewal string `json:"budgetRenewal"` Isolated bool `json:"isolated"` WalletPubkey string `json:"walletPubkey"` UniqueWalletPubkey bool `json:"uniqueWalletPubkey"` - Balance int64 `json:"balance"` + Balance int64 `json:"balance"` // deprecated + BalanceSat int64 `json:"balanceSat"` + BalanceMsat int64 `json:"balanceMsat"` Metadata Metadata `json:"metadata,omitempty"` } @@ -117,9 +123,11 @@ type ListAppsFilters struct { } type ListAppsResponse struct { - Apps []App `json:"apps"` - TotalCount uint64 `json:"totalCount"` - TotalBalance *int64 `json:"totalBalance,omitempty"` + Apps []App `json:"apps"` + TotalCount uint64 `json:"totalCount"` + TotalBalance *int64 `json:"totalBalance,omitempty"` // deprecated + TotalBalanceSat *int64 `json:"totalBalanceSat,omitempty"` + TotalBalanceMsat *int64 `json:"totalBalanceMsat,omitempty"` } type UpdateAppRequest struct { @@ -177,19 +185,24 @@ type EnableAutoSwapRequest struct { } type GetAutoSwapConfigResponse struct { - Type string `json:"type"` - Enabled bool `json:"enabled"` - BalanceThreshold uint64 `json:"balanceThreshold"` - SwapAmount uint64 `json:"swapAmount"` - Destination string `json:"destination"` + Type string `json:"type"` + Enabled bool `json:"enabled"` + BalanceThreshold uint64 `json:"balanceThreshold"` // deprecated + BalanceThresholdSat uint64 `json:"balanceThresholdSat"` + SwapAmount uint64 `json:"swapAmount"` // deprecated + SwapAmountSat uint64 `json:"swapAmountSat"` + Destination string `json:"destination"` } type SwapInfoResponse struct { - AlbyServiceFee float64 `json:"albyServiceFee"` - BoltzServiceFee float64 `json:"boltzServiceFee"` - BoltzNetworkFee uint64 `json:"boltzNetworkFee"` - MinAmount uint64 `json:"minAmount"` - MaxAmount uint64 `json:"maxAmount"` + AlbyServiceFee float64 `json:"albyServiceFee"` + BoltzServiceFee float64 `json:"boltzServiceFee"` + BoltzNetworkFee uint64 `json:"boltzNetworkFee"` // deprecated + BoltzNetworkFeeSat uint64 `json:"boltzNetworkFeeSat"` + MinAmount uint64 `json:"minAmount"` // deprecated + MinAmountSat uint64 `json:"minAmountSat"` + MaxAmount uint64 `json:"maxAmount"` // deprecated + MaxAmountSat uint64 `json:"maxAmountSat"` } type ListSwapsResponse struct { @@ -203,8 +216,10 @@ type Swap struct { Type string `json:"type"` State string `json:"state"` Invoice string `json:"invoice"` - SendAmount uint64 `json:"sendAmount"` - ReceiveAmount uint64 `json:"receiveAmount"` + SendAmount uint64 `json:"sendAmount"` // deprecated + SendAmountSat uint64 `json:"sendAmountSat"` + ReceiveAmount uint64 `json:"receiveAmount"` // deprecated + ReceiveAmountSat uint64 `json:"receiveAmountSat"` PaymentHash string `json:"paymentHash"` DestinationAddress string `json:"destinationAddress"` RefundAddress string `json:"refundAddress"` @@ -346,7 +361,8 @@ type RebalanceChannelRequest struct { AmountSat uint64 `json:"amountSat"` } type RebalanceChannelResponse struct { - TotalFeeSat uint64 `json:"totalFeeSat"` + TotalFeeSat uint64 `json:"totalFeeSat"` + TotalFeeMsat uint64 `json:"totalFeeMsat"` } type RedeemOnchainFundsRequest struct { @@ -381,8 +397,12 @@ type Transaction struct { DescriptionHash string `json:"descriptionHash"` Preimage *string `json:"preimage"` PaymentHash string `json:"paymentHash"` - Amount uint64 `json:"amount"` - FeesPaid uint64 `json:"feesPaid"` + Amount uint64 `json:"amount"` // deprecated + AmountSat uint64 `json:"amountSat"` + AmountMsat uint64 `json:"amountMsat"` + FeesPaid uint64 `json:"feesPaid"` // deprecated + FeesPaidSat uint64 `json:"feesPaidSat"` + FeesPaidMsat uint64 `json:"feesPaidMsat"` UpdatedAt string `json:"updatedAt"` CreatedAt string `json:"createdAt"` SettledAt *string `json:"settledAt"` @@ -408,6 +428,7 @@ type Boostagram struct { SenderName string `json:"senderName"` Time string `json:"time"` Action string `json:"action"` + ValueSatTotal int64 `json:"valueSatTotal"` ValueMsatTotal int64 `json:"valueMsatTotal"` } @@ -487,11 +508,15 @@ type LSPOrderRequest struct { } type LSPOrderResponse struct { - Invoice string `json:"invoice"` - Fee uint64 `json:"fee"` - InvoiceAmount uint64 `json:"invoiceAmount"` - IncomingLiquidity uint64 `json:"incomingLiquidity"` - OutgoingLiquidity uint64 `json:"outgoingLiquidity"` + Invoice string `json:"invoice"` + Fee uint64 `json:"fee"` // deprecated + FeeSat uint64 `json:"feeSat"` + InvoiceAmount uint64 `json:"invoiceAmount"` // deprecated + InvoiceAmountSat uint64 `json:"invoiceAmountSat"` + IncomingLiquidity uint64 `json:"incomingLiquidity"` // deprecated + IncomingLiquiditySat uint64 `json:"incomingLiquiditySat"` + OutgoingLiquidity uint64 `json:"outgoingLiquidity"` // deprecated + OutgoingLiquiditySat uint64 `json:"outgoingLiquiditySat"` } type WalletCapabilitiesResponse struct { @@ -501,25 +526,33 @@ type WalletCapabilitiesResponse struct { } type Channel struct { - LocalBalance int64 `json:"localBalance"` - LocalSpendableBalance int64 `json:"localSpendableBalance"` - RemoteBalance int64 `json:"remoteBalance"` - Id string `json:"id"` - RemotePubkey string `json:"remotePubkey"` - FundingTxId string `json:"fundingTxId"` - FundingTxVout uint32 `json:"fundingTxVout"` - Active bool `json:"active"` - Public bool `json:"public"` - InternalChannel interface{} `json:"internalChannel"` - Confirmations *uint32 `json:"confirmations"` - ConfirmationsRequired *uint32 `json:"confirmationsRequired"` - ForwardingFeeBaseMsat uint32 `json:"forwardingFeeBaseMsat"` - ForwardingFeeProportionalMillionths uint32 `json:"forwardingFeeProportionalMillionths"` - UnspendablePunishmentReserve uint64 `json:"unspendablePunishmentReserve"` - CounterpartyUnspendablePunishmentReserve uint64 `json:"counterpartyUnspendablePunishmentReserve"` - Error *string `json:"error"` - Status string `json:"status"` - IsOutbound bool `json:"isOutbound"` + LocalBalance int64 `json:"localBalance"` // deprecated + LocalBalanceSat int64 `json:"localBalanceSat"` + LocalBalanceMsat int64 `json:"localBalanceMsat"` + LocalSpendableBalance int64 `json:"localSpendableBalance"` // deprecated + LocalSpendableBalanceSat int64 `json:"localSpendableBalanceSat"` + LocalSpendableBalanceMsat int64 `json:"localSpendableBalanceMsat"` + RemoteBalance int64 `json:"remoteBalance"` // deprecated + RemoteBalanceSat int64 `json:"remoteBalanceSat"` + RemoteBalanceMsat int64 `json:"remoteBalanceMsat"` + Id string `json:"id"` + RemotePubkey string `json:"remotePubkey"` + FundingTxId string `json:"fundingTxId"` + FundingTxVout uint32 `json:"fundingTxVout"` + Active bool `json:"active"` + Public bool `json:"public"` + InternalChannel interface{} `json:"internalChannel"` + Confirmations *uint32 `json:"confirmations"` + ConfirmationsRequired *uint32 `json:"confirmationsRequired"` + ForwardingFeeBaseMsat uint32 `json:"forwardingFeeBaseMsat"` // expressed only in msat as per Lightning spec + ForwardingFeeProportionalMillionths uint32 `json:"forwardingFeeProportionalMillionths"` + UnspendablePunishmentReserve uint64 `json:"unspendablePunishmentReserve"` // deprecated + UnspendablePunishmentReserveSat uint64 `json:"unspendablePunishmentReserveSat"` + CounterpartyUnspendablePunishmentReserve uint64 `json:"counterpartyUnspendablePunishmentReserve"` // deprecated + CounterpartyUnspendablePunishmentReserveSat uint64 `json:"counterpartyUnspendablePunishmentReserveSat"` + Error *string `json:"error"` + Status string `json:"status"` + IsOutbound bool `json:"isOutbound"` } type MigrateNodeStorageRequest struct { @@ -572,7 +605,9 @@ type ExecuteCustomNodeCommandRequest struct { } type GetForwardsResponse struct { + OutboundAmountForwardedSat uint64 `json:"outboundAmountForwardedSat"` OutboundAmountForwardedMsat uint64 `json:"outboundAmountForwardedMsat"` + TotalFeeEarnedSat uint64 `json:"totalFeeEarnedSat"` TotalFeeEarnedMsat uint64 `json:"totalFeeEarnedMsat"` NumForwards uint64 `json:"numForwards"` } diff --git a/api/rebalance.go b/api/rebalance.go index 31fd87cd..35ea7612 100644 --- a/api/rebalance.go +++ b/api/rebalance.go @@ -138,7 +138,10 @@ func (api *api) RebalanceChannel(ctx context.Context, rebalanceChannelRequest *R Properties: map[string]interface{}{}, }) + totalFeeMsat := uint64(paymentRequest.MSatoshi) + payRebalanceInvoiceResponse.FeeMsat - rebalanceChannelRequest.AmountSat*1000 + return &RebalanceChannelResponse{ - TotalFeeSat: uint64(paymentRequest.MSatoshi)/1000 + payRebalanceInvoiceResponse.FeeMsat/1000 - rebalanceChannelRequest.AmountSat, + TotalFeeSat: totalFeeMsat / 1000, + TotalFeeMsat: totalFeeMsat, }, nil } diff --git a/api/transactions.go b/api/transactions.go index 2ba01c3b..35715486 100644 --- a/api/transactions.go +++ b/api/transactions.go @@ -12,12 +12,12 @@ import ( "github.com/sirupsen/logrus" ) -func (api *api) CreateInvoice(ctx context.Context, amount uint64, description string) (*MakeInvoiceResponse, error) { +func (api *api) CreateInvoice(ctx context.Context, amountMsat uint64, description string) (*MakeInvoiceResponse, error) { lnClient := api.svc.GetLNClient() if lnClient == nil { return nil, ErrLNClientNotStarted } - transaction, err := api.svc.GetTransactionsService().MakeInvoice(ctx, amount, description, "", 0, nil, lnClient, nil, nil, nil) + transaction, err := api.svc.GetTransactionsService().MakeInvoice(ctx, amountMsat, description, "", 0, nil, lnClient, nil, nil, nil) if err != nil { return nil, err } @@ -121,8 +121,12 @@ func toApiTransaction(transaction *transactions.Transaction) *Transaction { Preimage: preimage, PaymentHash: transaction.PaymentHash, Amount: transaction.AmountMsat, + AmountSat: transaction.AmountMsat / 1000, + AmountMsat: transaction.AmountMsat, AppId: transaction.AppId, FeesPaid: transaction.FeeMsat, + FeesPaidSat: transaction.FeeMsat / 1000, + FeesPaidMsat: transaction.FeeMsat, UpdatedAt: updatedAt, CreatedAt: createdAt, SettledAt: settledAt, @@ -180,6 +184,7 @@ func toApiBoostagram(boostagram *transactions.Boostagram) *Boostagram { SenderName: boostagram.SenderName, Time: boostagram.Time, Action: boostagram.Action, + ValueSatTotal: boostagram.ValueMsatTotal / 1000, ValueMsatTotal: boostagram.ValueMsatTotal, } } diff --git a/db/queries/get_budget_usage.go b/db/queries/get_budget_usage.go index 92a1fb4f..0fa57461 100644 --- a/db/queries/get_budget_usage.go +++ b/db/queries/get_budget_usage.go @@ -8,7 +8,7 @@ import ( "gorm.io/gorm" ) -func GetBudgetUsage(tx *gorm.DB, appPermission *db.AppPermission) (uint64, error) { +func GetBudgetUsageMsat(tx *gorm.DB, appPermission *db.AppPermission) (uint64, error) { var result struct { Sum uint64 } diff --git a/db/queries/get_budget_usage_test.go b/db/queries/get_budget_usage_test.go index 8853dc4d..5a4eba1d 100644 --- a/db/queries/get_budget_usage_test.go +++ b/db/queries/get_budget_usage_test.go @@ -45,9 +45,9 @@ func TestGetBudgetUsage_IncludesPendingAndSettledOutgoing(t *testing.T) { FeeReserveMsat: 500, }).Error) - budgetUsage, err := GetBudgetUsage(svc.DB, appPermission) + budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermission) require.NoError(t, err) - assert.Equal(t, uint64(79000), budgetUsage) + assert.Equal(t, uint64(79000), budgetUsageMsat) } func TestGetBudgetUsage_ExcludesWrongStateTypeAndApp(t *testing.T) { @@ -104,9 +104,9 @@ func TestGetBudgetUsage_ExcludesWrongStateTypeAndApp(t *testing.T) { FeeReserveMsat: 0, }).Error) - budgetUsage, err := GetBudgetUsage(svc.DB, appPermission) + budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermission) require.NoError(t, err) - assert.Equal(t, uint64(21000), budgetUsage) + assert.Equal(t, uint64(21000), budgetUsageMsat) } func TestGetBudgetUsage_BudgetWindowDaily(t *testing.T) { @@ -146,9 +146,9 @@ func TestGetBudgetUsage_BudgetWindowDaily(t *testing.T) { CreatedAt: dailyStart.Add(2 * time.Hour), }).Error) - budgetUsage, err := GetBudgetUsage(svc.DB, appPermissionDaily) + budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermissionDaily) require.NoError(t, err) - assert.Equal(t, uint64(42000), budgetUsage) + assert.Equal(t, uint64(42000), budgetUsageMsat) } func TestGetBudgetUsage_BudgetWindowWeekly(t *testing.T) { @@ -188,9 +188,9 @@ func TestGetBudgetUsage_BudgetWindowWeekly(t *testing.T) { CreatedAt: weeklyStart.Add(-1 * time.Hour), }).Error) - budgetUsage, err := GetBudgetUsage(svc.DB, appPermissionWeekly) + budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermissionWeekly) require.NoError(t, err) - assert.Equal(t, uint64(11000), budgetUsage) + assert.Equal(t, uint64(11000), budgetUsageMsat) } func TestGetBudgetUsage_BudgetWindowNever(t *testing.T) { @@ -228,7 +228,7 @@ func TestGetBudgetUsage_BudgetWindowNever(t *testing.T) { CreatedAt: time.Now().AddDate(-1, 0, 0), }).Error) - budgetUsage, err := GetBudgetUsage(svc.DB, appPermission) + budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermission) require.NoError(t, err) - assert.Equal(t, uint64(11000), budgetUsage) + assert.Equal(t, uint64(11000), budgetUsageMsat) } diff --git a/db/queries/get_isolated_balance.go b/db/queries/get_isolated_balance.go index c8a9819a..ab5dcd7c 100644 --- a/db/queries/get_isolated_balance.go +++ b/db/queries/get_isolated_balance.go @@ -5,7 +5,7 @@ import ( "gorm.io/gorm" ) -func GetIsolatedBalance(tx *gorm.DB, appId uint) (int64, error) { +func GetIsolatedBalanceMsat(tx *gorm.DB, appId uint) (int64, error) { var received struct { Sum int64 } diff --git a/db/queries/get_isolated_balance_test.go b/db/queries/get_isolated_balance_test.go index f923c5b5..925b0f36 100644 --- a/db/queries/get_isolated_balance_test.go +++ b/db/queries/get_isolated_balance_test.go @@ -36,9 +36,9 @@ func TestGetIsolatedBalance_PendingNoOverflow(t *testing.T) { } svc.DB.Save(&tx) - balance, err := GetIsolatedBalance(svc.DB, app.ID) + balanceMsat, err := GetIsolatedBalanceMsat(svc.DB, app.ID) require.NoError(t, err) - assert.Equal(t, int64(-11000), balance) + assert.Equal(t, int64(-11000), balanceMsat) } func TestGetIsolatedBalance_SettledNoOverflow(t *testing.T) { @@ -66,7 +66,7 @@ func TestGetIsolatedBalance_SettledNoOverflow(t *testing.T) { } svc.DB.Save(&tx) - balance, err := GetIsolatedBalance(svc.DB, app.ID) + balanceMsat, err := GetIsolatedBalanceMsat(svc.DB, app.ID) require.NoError(t, err) - assert.Equal(t, int64(-1000), balance) + assert.Equal(t, int64(-1000), balanceMsat) } diff --git a/db/queries/get_total_subwallet_balance.go b/db/queries/get_total_subwallet_balance.go index 42d82a4a..22860c95 100644 --- a/db/queries/get_total_subwallet_balance.go +++ b/db/queries/get_total_subwallet_balance.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" ) -func GetTotalSubwalletBalance(tx *gorm.DB) (int64, error) { +func GetTotalSubwalletBalanceMsat(tx *gorm.DB) (int64, error) { subwalletAppIDsQuery := tx.Model(&db.App{}). Select("id"). Where(datatypes.JSONQuery("metadata").Equals(constants.SUBWALLET_APPSTORE_APP_ID, constants.METADATA_APPSTORE_APP_ID_KEY)) diff --git a/db/queries/get_total_subwallet_balance_test.go b/db/queries/get_total_subwallet_balance_test.go index 150c7557..a5a1bf41 100644 --- a/db/queries/get_total_subwallet_balance_test.go +++ b/db/queries/get_total_subwallet_balance_test.go @@ -58,7 +58,7 @@ func TestGetTotalSubwalletBalance(t *testing.T) { } svc.DB.Save(&outgoingPendingSubwalletTx) - total, err := GetTotalSubwalletBalance(svc.DB) + totalBalanceMsat, err := GetTotalSubwalletBalanceMsat(svc.DB) require.NoError(t, err) - assert.Equal(t, int64(1600), total) + assert.Equal(t, int64(1600), totalBalanceMsat) } diff --git a/frontend/src/screens/channels/IncreaseOutgoingCapacity.tsx b/frontend/src/screens/channels/IncreaseOutgoingCapacity.tsx index cca20bca..fba747ce 100644 --- a/frontend/src/screens/channels/IncreaseOutgoingCapacity.tsx +++ b/frontend/src/screens/channels/IncreaseOutgoingCapacity.tsx @@ -106,7 +106,9 @@ function NewChannelInternal({ network, paymentMethod: "onchain", minimumChannelSize: 0, + minimumChannelSizeSat: 0, maximumChannelSize: 0, + maximumChannelSizeSat: 0, description: "", pubkey: "", host: "", diff --git a/frontend/src/types.ts b/frontend/src/types.ts index 3567c9a6..2d8e3e5f 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -121,11 +121,17 @@ export interface App { lastSettledTransactionAt?: string; expiresAt?: string; isolated: boolean; - balance: number; + balance: number; // @depreated + balanceSat: number; + balanceMsat: number; scopes: Scope[]; - maxAmount: number; - budgetUsage: number; + maxAmount: number; // @depreated + maxAmountSat: number; + maxAmountMsat: number; + budgetUsage: number; // @depreated + budgetUsageSat: number; + budgetUsageMsat: number; budgetRenewal: BudgetRenewalType; metadata?: AppMetadata; } @@ -203,22 +209,28 @@ export type AppMetadata = { export type AutoSwapConfig = { type: "out"; enabled: boolean; - balanceThreshold: number; - swapAmount: number; + balanceThreshold: number; // @depreated + balanceThresholdSat: number; + swapAmount: number; // @depreated + swapAmountSat: number; destination: string; }; export type SwapInfo = { albyServiceFee: number; boltzServiceFee: number; - boltzNetworkFee: number; - minAmount: number; - maxAmount: number; + boltzNetworkFee: number; // @depreated + boltzNetworkFeeSat: number; + minAmount: number; // @depreated + minAmountSat: number; + maxAmount: number; // @depreated + maxAmountSat: number; }; export type BaseSwap = { id: string; - sendAmount: number; + sendAmount: number; // @depreated + sendAmountSat: number; lockupAddress: string; paymentHash: string; invoice: string; @@ -229,7 +241,8 @@ export type BaseSwap = { updatedAt: string; lockupTxId?: string; claimTxId?: string; - receiveAmount?: number; + receiveAmount?: number; // @depreated + receiveAmountSat?: number; }; export type SwapIn = BaseSwap & { @@ -292,9 +305,15 @@ export type UpdateAppRequest = { }; export type Channel = { - localBalance: number; - localSpendableBalance: number; - remoteBalance: number; + localBalance: number; // @depreated + localBalanceSat: number; + localBalanceMsat: number; + localSpendableBalance: number; // @depreated + localSpendableBalanceSat: number; + localSpendableBalanceMsat: number; + remoteBalance: number; // @depreated + remoteBalanceSat: number; + remoteBalanceMsat: number; remotePubkey: string; id: string; fundingTxId: string; @@ -305,8 +324,10 @@ export type Channel = { confirmationsRequired?: number; forwardingFeeBaseMsat: number; forwardingFeeProportionalMillionths: number; - unspendablePunishmentReserve: number; - counterpartyUnspendablePunishmentReserve: number; + unspendablePunishmentReserve: number; // @depreated + unspendablePunishmentReserveSat: number; + counterpartyUnspendablePunishmentReserve: number; // @depreated + counterpartyUnspendablePunishmentReserveSat: number; error?: string; status: "online" | "opening" | "offline"; isOutbound: boolean; @@ -374,16 +395,21 @@ export type CloseChannelResponse = {}; export type PendingBalancesDetails = { channelId: string; nodeId: string; - amount: number; + amount: number; // @depreated + amountSat: number; fundingTxId: string; fundingTxVout: number; }; export type OnchainBalanceResponse = { - spendable: number; - total: number; - reserved: number; - pendingBalancesFromChannelClosures: number; + spendable: number; // @depreated + spendableSat: number; + total: number; // @depreated + totalSat: number; + reserved: number; // @depreated + reservedSat: number; + pendingBalancesFromChannelClosures: number; // @depreated + pendingBalancesFromChannelClosuresSat: number; pendingBalancesDetails: PendingBalancesDetails[]; pendingSweepBalancesDetails: PendingBalancesDetails[]; }; @@ -469,8 +495,10 @@ export type RecommendedChannelPeer = { network: Network; image: string; name: string; - minimumChannelSize: number; - maximumChannelSize: number; + minimumChannelSize: number; // @depreated + minimumChannelSizeSat: number; + maximumChannelSize: number; // @depreated + maximumChannelSizeSat: number; note: string; publicChannelsAllowed: boolean; description: string; @@ -546,10 +574,14 @@ export type LSPOrderRequest = { export type LSPOrderResponse = { invoice?: string; - fee: number; - invoiceAmount: number; - incomingLiquidity: number; - outgoingLiquidity: number; + fee: number; // @depreated + feeSat: number; + invoiceAmount: number; // @depreated + invoiceAmountSat: number; + incomingLiquidity: number; // @depreated + incomingLiquiditySat: number; + outgoingLiquidity: number; // @depreated + outgoingLiquiditySat: number; }; export type AutoChannelRequest = { @@ -557,8 +589,10 @@ export type AutoChannelRequest = { }; export type AutoChannelResponse = { invoice?: string; - fee?: number; - channelSize: number; + fee?: number; // @depreated + feeSat?: number; + channelSize: number; // @depreated + channelSizeSat: number; }; export type RedeemOnchainFundsResponse = { @@ -566,12 +600,24 @@ export type RedeemOnchainFundsResponse = { }; export type LightningBalanceResponse = { - totalSpendable: number; - totalReceivable: number; - nextMaxSpendable: number; - nextMaxReceivable: number; - nextMaxSpendableMPP: number; - nextMaxReceivableMPP: number; + totalSpendable: number; // @depreated + totalSpendableSat: number; + totalSpendableMsat: number; + totalReceivable: number; // @depreated + totalReceivableSat: number; + totalReceivableMsat: number; + nextMaxSpendable: number; // @depreated + nextMaxSpendableSat: number; + nextMaxSpendableMsat: number; + nextMaxReceivable: number; // @depreated + nextMaxReceivableSat: number; + nextMaxReceivableMsat: number; + nextMaxSpendableMPP: number; // @depreated + nextMaxSpendableMPPSat: number; + nextMaxSpendableMPPMsat: number; + nextMaxReceivableMPP: number; // @depreated + nextMaxReceivableMPPSat: number; + nextMaxReceivableMPPMsat: number; }; export type BalancesResponse = { @@ -588,8 +634,12 @@ export type Transaction = { descriptionHash: string; preimage: string | undefined; paymentHash: string; - amount: number; - feesPaid: number; + amount: number; // @depreated + amountSat: number; + amountMsat: number; + feesPaid: number; // @depreated + feesPaidSat: number; + feesPaidMsat: number; updatedAt: string; createdAt: string; settledAt: string | undefined; @@ -633,11 +683,13 @@ export type Boostagram = { senderName: string; time: string; action: "boost"; + valueSatTotal: number; valueMsatTotal: number; }; export type OnchainTransaction = { amountSat: number; + amountMsat: number; createdAt: number; type: "incoming" | "outgoing"; state: "confirmed" | "unconfirmed"; @@ -648,7 +700,9 @@ export type OnchainTransaction = { export type ListAppsResponse = { apps: App[]; totalCount: number; - totalBalance?: number; + totalBalance?: number; // @depreated + totalBalanceSat?: number; + totalBalanceMsat?: number; }; export type ListTransactionsResponse = { @@ -685,7 +739,9 @@ export type AuthTokenResponse = { }; export type GetForwardsResponse = { + outboundAmountForwardedSat: number; outboundAmountForwardedMsat: number; + totalFeeEarnedSat: number; totalFeeEarnedMsat: number; numForwards: number; }; diff --git a/lnclient/cashu/cashu.go b/lnclient/cashu/cashu.go index 40fc3836..33f5f52e 100644 --- a/lnclient/cashu/cashu.go +++ b/lnclient/cashu/cashu.go @@ -187,10 +187,7 @@ func (cs *CashuService) GetNewOnchainAddress(ctx context.Context) (string, error } func (cs *CashuService) GetOnchainBalance(ctx context.Context) (*lnclient.OnchainBalanceResponse, error) { - return &lnclient.OnchainBalanceResponse{ - Spendable: 0, - Total: 0, - }, nil + return &lnclient.OnchainBalanceResponse{}, nil } func (cs *CashuService) RedeemOnchainFunds(ctx context.Context, toAddress string, amount uint64, feeRate *uint64, sendAll bool) (string, error) { @@ -267,16 +264,18 @@ func (cs *CashuService) GetBalances(ctx context.Context, includeInactiveChannels return &lnclient.BalancesResponse{ Onchain: lnclient.OnchainBalanceResponse{ - Spendable: 0, - Total: 0, - }, + PendingBalancesDetails: []lnclient.PendingBalanceDetails{}, + PendingSweepBalancesDetails: []lnclient.PendingBalanceDetails{}}, Lightning: lnclient.LightningBalanceResponse{ - TotalSpendable: balance, - TotalReceivable: 0, - NextMaxSpendable: balance, - NextMaxReceivable: 0, - NextMaxSpendableMPP: balance, - NextMaxReceivableMPP: 0, + TotalSpendable: balance, + TotalSpendableSat: balance / 1000, + TotalSpendableMsat: balance, + NextMaxSpendable: balance, + NextMaxSpendableSat: balance / 1000, + NextMaxSpendableMsat: balance, + NextMaxSpendableMPP: balance, + NextMaxSpendableMPPSat: balance / 1000, + NextMaxSpendableMPPMsat: balance, }, }, nil } diff --git a/lnclient/ldk/ldk.go b/lnclient/ldk/ldk.go index 872e4e40..c70e2e4c 100644 --- a/lnclient/ldk/ldk.go +++ b/lnclient/ldk/ldk.go @@ -553,7 +553,7 @@ func (ls *LDKService) SendPaymentSync(invoice string, amount *uint64) (*lnclient logger.Logger.WithError(err).Error("SendPayment failed") return nil, err } - fee := uint64(0) + feeMsat := uint64(0) preimage := "" for { @@ -579,18 +579,18 @@ func (ls *LDKService) SendPaymentSync(invoice string, amount *uint64) (*lnclient preimage = *event.PaymentPreimage if event.FeePaidMsat != nil { - fee = *event.FeePaidMsat + feeMsat = *event.FeePaidMsat } logger.Logger.WithFields(logrus.Fields{ "duration": time.Since(paymentStart).Milliseconds(), - "fee": fee, + "fee": feeMsat, "payment_hash": event.PaymentHash, }).Info("Successful payment") return &lnclient.PayInvoiceResponse{ Preimage: preimage, - Fee: fee, + Fee: feeMsat, }, nil case ldk_node.EventPaymentFailed: if event.PaymentHash != nil && *event.PaymentHash == paymentHash { @@ -640,7 +640,7 @@ func (ls *LDKService) SendKeysend(amount uint64, destination string, custom_reco logger.Logger.WithError(err).Error("Keysend failed") return nil, err } - fee := uint64(0) + feeMsat := uint64(0) for { select { case <-ls.ctx.Done(): @@ -654,14 +654,14 @@ func (ls *LDKService) SendKeysend(amount uint64, destination string, custom_reco logger.Logger.Info("Got payment success event") if eventPaymentSuccessful.FeePaidMsat != nil { - fee = *eventPaymentSuccessful.FeePaidMsat + feeMsat = *eventPaymentSuccessful.FeePaidMsat } logger.Logger.WithFields(logrus.Fields{ "duration": time.Since(paymentStart).Milliseconds(), - "fee": fee, + "fee": feeMsat, }).Info("Successful keysend payment") return &lnclient.PayKeysendResponse{ - Fee: fee, + Fee: feeMsat, }, nil } if isEventPaymentFailedEvent && eventPaymentFailed.PaymentHash != nil && *eventPaymentFailed.PaymentHash == paymentHash { @@ -1150,6 +1150,7 @@ func (ls *LDKService) GetOnchainBalance(ctx context.Context) (*lnclient.OnchainB NodeId: nodeId, ChannelId: channelId, Amount: amount, + AmountSat: amount, FundingTxId: fundingTxId, FundingTxVout: uint32(fundingTxIndex), }) @@ -1186,6 +1187,7 @@ func (ls *LDKService) GetOnchainBalance(ctx context.Context) (*lnclient.OnchainB NodeId: *nodeId, ChannelId: *channelId, Amount: amount, + AmountSat: amount, FundingTxId: *fundingTxId, FundingTxVout: uint32(*fundingTxIndex), }) @@ -1210,12 +1212,16 @@ func (ls *LDKService) GetOnchainBalance(ctx context.Context) (*lnclient.OnchainB } return &lnclient.OnchainBalanceResponse{ - Spendable: int64(balances.SpendableOnchainBalanceSats), - Total: int64(balances.TotalOnchainBalanceSats - balances.TotalAnchorChannelsReserveSats), - Reserved: int64(balances.TotalAnchorChannelsReserveSats), - PendingBalancesFromChannelClosures: pendingBalancesFromChannelClosures, - PendingBalancesDetails: pendingBalancesDetails, - PendingSweepBalancesDetails: pendingSweepBalanceDetails, + Spendable: int64(balances.SpendableOnchainBalanceSats), + SpendableSat: int64(balances.SpendableOnchainBalanceSats), + Total: int64(balances.TotalOnchainBalanceSats - balances.TotalAnchorChannelsReserveSats), + TotalSat: int64(balances.TotalOnchainBalanceSats - balances.TotalAnchorChannelsReserveSats), + Reserved: int64(balances.TotalAnchorChannelsReserveSats), + ReservedSat: int64(balances.TotalAnchorChannelsReserveSats), + PendingBalancesFromChannelClosures: pendingBalancesFromChannelClosures, + PendingBalancesFromChannelClosuresSat: pendingBalancesFromChannelClosures, + PendingBalancesDetails: pendingBalancesDetails, + PendingSweepBalancesDetails: pendingSweepBalanceDetails, InternalBalances: map[string]interface{}{ "internal_lightning_balances": internalLightningBalances, "all_balances": balances, @@ -1420,14 +1426,14 @@ func (ls *LDKService) ldkPaymentToTransaction(payment *ldk_node.PaymentDetails) metadata["tlv_records"] = tlvRecords } - var amount uint64 = 0 + var amountMsat uint64 = 0 if payment.AmountMsat != nil { - amount = *payment.AmountMsat + amountMsat = *payment.AmountMsat } - var fee uint64 = 0 + var feeMsat uint64 = 0 if payment.FeePaidMsat != nil { - fee = *payment.FeePaidMsat + feeMsat = *payment.FeePaidMsat } return &lnclient.Transaction{ @@ -1435,9 +1441,9 @@ func (ls *LDKService) ldkPaymentToTransaction(payment *ldk_node.PaymentDetails) Preimage: preimage, PaymentHash: paymentHash, SettledAt: settledAt, - Amount: int64(amount), + Amount: int64(amountMsat), Invoice: bolt11Invoice, - FeesPaid: int64(fee), + FeesPaid: int64(feeMsat), CreatedAt: createdAt, Description: description, DescriptionHash: descriptionHash, @@ -1870,12 +1876,24 @@ func (ls *LDKService) GetBalances(ctx context.Context, includeInactiveChannels b return &lnclient.BalancesResponse{ Onchain: *onchainBalance, Lightning: lnclient.LightningBalanceResponse{ - TotalSpendable: totalSpendable, - TotalReceivable: totalReceivable, - NextMaxSpendable: nextMaxSpendable, - NextMaxReceivable: nextMaxReceivable, - NextMaxSpendableMPP: nextMaxSpendableMPP, - NextMaxReceivableMPP: nextMaxReceivableMPP, + TotalSpendable: totalSpendable, + TotalSpendableSat: totalSpendable / 1000, + TotalSpendableMsat: totalSpendable, + TotalReceivable: totalReceivable, + TotalReceivableSat: totalReceivable / 1000, + TotalReceivableMsat: totalReceivable, + NextMaxSpendable: nextMaxSpendable, + NextMaxSpendableSat: nextMaxSpendable / 1000, + NextMaxSpendableMsat: nextMaxSpendable, + NextMaxReceivable: nextMaxReceivable, + NextMaxReceivableSat: nextMaxReceivable / 1000, + NextMaxReceivableMsat: nextMaxReceivable, + NextMaxSpendableMPP: nextMaxSpendableMPP, + NextMaxSpendableMPPSat: nextMaxSpendableMPP / 1000, + NextMaxSpendableMPPMsat: nextMaxSpendableMPP, + NextMaxReceivableMPP: nextMaxReceivableMPP, + NextMaxReceivableMPPSat: nextMaxReceivableMPP / 1000, + NextMaxReceivableMPPMsat: nextMaxReceivableMPP, }, }, nil } @@ -2332,20 +2350,20 @@ func (ls *LDKService) MakeHoldInvoice(ctx context.Context, amount int64, descrip if *minCltvExpiryDelta > uint64(65535) { return nil, errors.New("min_cltv_expiry_delta must be <= 65535") } - invoiceObj, err = ls.node.Bolt11Payment().ReceiveForHashWithMinCltvExpiryDelta( - uint64(amount), - descriptionType, - uint32(expiry), - ldkPaymentHash, - uint16(*minCltvExpiryDelta), - ) + invoiceObj, err = ls.node.Bolt11Payment().ReceiveForHashWithMinCltvExpiryDelta( + uint64(amount), + descriptionType, + uint32(expiry), + ldkPaymentHash, + uint16(*minCltvExpiryDelta), + ) } else { - invoiceObj, err = ls.node.Bolt11Payment().ReceiveForHash( - uint64(amount), - descriptionType, - uint32(expiry), - ldkPaymentHash, - ) + invoiceObj, err = ls.node.Bolt11Payment().ReceiveForHash( + uint64(amount), + descriptionType, + uint32(expiry), + ldkPaymentHash, + ) } if err != nil { diff --git a/lnclient/lnd/lnd.go b/lnclient/lnd/lnd.go index 1e4fcead..02b08551 100644 --- a/lnclient/lnd/lnd.go +++ b/lnclient/lnd/lnd.go @@ -1264,6 +1264,7 @@ func (svc *LNDService) GetOnchainBalance(ctx context.Context) (*lnclient.Onchain pendingBalancesDetails = append(pendingBalancesDetails, lnclient.PendingBalanceDetails{ NodeId: closingChannel.Channel.RemoteNodePub, Amount: uint64(closingChannel.LimboBalance), + AmountSat: uint64(closingChannel.LimboBalance), FundingTxId: channelPoint.GetFundingTxidStr(), FundingTxVout: channelPoint.GetOutputIndex(), }) @@ -1273,12 +1274,16 @@ func (svc *LNDService) GetOnchainBalance(ctx context.Context) (*lnclient.Onchain "balances": balances, }).Debug("Listed Balances") return &lnclient.OnchainBalanceResponse{ - Spendable: int64(balances.ConfirmedBalance), - Total: int64(balances.TotalBalance), - Reserved: int64(balances.ReservedBalanceAnchorChan), - PendingBalancesFromChannelClosures: pendingBalancesFromChannelClosures, - PendingBalancesDetails: pendingBalancesDetails, - PendingSweepBalancesDetails: []lnclient.PendingBalanceDetails{}, + Spendable: int64(balances.ConfirmedBalance), + SpendableSat: int64(balances.ConfirmedBalance), + Total: int64(balances.TotalBalance), + TotalSat: int64(balances.TotalBalance), + Reserved: int64(balances.ReservedBalanceAnchorChan), + ReservedSat: int64(balances.ReservedBalanceAnchorChan), + PendingBalancesFromChannelClosures: pendingBalancesFromChannelClosures, + PendingBalancesFromChannelClosuresSat: pendingBalancesFromChannelClosures, + PendingBalancesDetails: pendingBalancesDetails, + PendingSweepBalancesDetails: []lnclient.PendingBalanceDetails{}, InternalBalances: map[string]interface{}{ "balances": balances, "pending_channels": pendingChannels, @@ -1449,12 +1454,24 @@ func (svc *LNDService) GetBalances(ctx context.Context, includeInactiveChannels return &lnclient.BalancesResponse{ Onchain: *onchainBalance, Lightning: lnclient.LightningBalanceResponse{ - TotalSpendable: totalSpendable, - TotalReceivable: totalReceivable, - NextMaxSpendable: nextMaxSpendable, - NextMaxReceivable: nextMaxReceivable, - NextMaxSpendableMPP: nextMaxSpendableMPP, - NextMaxReceivableMPP: nextMaxReceivableMPP, + TotalSpendable: totalSpendable, + TotalSpendableSat: totalSpendable / 1000, + TotalSpendableMsat: totalSpendable, + TotalReceivable: totalReceivable, + TotalReceivableSat: totalReceivable / 1000, + TotalReceivableMsat: totalReceivable, + NextMaxSpendable: nextMaxSpendable, + NextMaxSpendableSat: nextMaxSpendable / 1000, + NextMaxSpendableMsat: nextMaxSpendable, + NextMaxReceivable: nextMaxReceivable, + NextMaxReceivableSat: nextMaxReceivable / 1000, + NextMaxReceivableMsat: nextMaxReceivable, + NextMaxSpendableMPP: nextMaxSpendableMPP, + NextMaxSpendableMPPSat: nextMaxSpendableMPP / 1000, + NextMaxSpendableMPPMsat: nextMaxSpendableMPP, + NextMaxReceivableMPP: nextMaxReceivableMPP, + NextMaxReceivableMPPSat: nextMaxReceivableMPP / 1000, + NextMaxReceivableMPPMsat: nextMaxReceivableMPP, }, }, nil } diff --git a/lnclient/models.go b/lnclient/models.go index 56092b95..1a0474ac 100644 --- a/lnclient/models.go +++ b/lnclient/models.go @@ -158,19 +158,24 @@ type CloseChannelResponse struct { type PendingBalanceDetails struct { ChannelId string `json:"channelId"` NodeId string `json:"nodeId"` - Amount uint64 `json:"amount"` + Amount uint64 `json:"amount"` // deprecated + AmountSat uint64 `json:"amountSat"` FundingTxId string `json:"fundingTxId"` FundingTxVout uint32 `json:"fundingTxVout"` } type OnchainBalanceResponse struct { - Spendable int64 `json:"spendable"` - Total int64 `json:"total"` - Reserved int64 `json:"reserved"` - PendingBalancesFromChannelClosures uint64 `json:"pendingBalancesFromChannelClosures"` - PendingBalancesDetails []PendingBalanceDetails `json:"pendingBalancesDetails"` - PendingSweepBalancesDetails []PendingBalanceDetails `json:"pendingSweepBalancesDetails"` - InternalBalances interface{} `json:"internalBalances"` + Spendable int64 `json:"spendable"` // deprecated + SpendableSat int64 `json:"spendableSat"` + Total int64 `json:"total"` // deprecated + TotalSat int64 `json:"totalSat"` + Reserved int64 `json:"reserved"` // deprecated + ReservedSat int64 `json:"reservedSat"` + PendingBalancesFromChannelClosures uint64 `json:"pendingBalancesFromChannelClosures"` // deprecated + PendingBalancesFromChannelClosuresSat uint64 `json:"pendingBalancesFromChannelClosuresSat"` + PendingBalancesDetails []PendingBalanceDetails `json:"pendingBalancesDetails"` + PendingSweepBalancesDetails []PendingBalanceDetails `json:"pendingSweepBalancesDetails"` + InternalBalances interface{} `json:"internalBalances"` } type PeerDetails struct { @@ -180,12 +185,24 @@ type PeerDetails struct { IsConnected bool `json:"isConnected"` } type LightningBalanceResponse struct { - TotalSpendable int64 `json:"totalSpendable"` - TotalReceivable int64 `json:"totalReceivable"` - NextMaxSpendable int64 `json:"nextMaxSpendable"` - NextMaxReceivable int64 `json:"nextMaxReceivable"` - NextMaxSpendableMPP int64 `json:"nextMaxSpendableMPP"` - NextMaxReceivableMPP int64 `json:"nextMaxReceivableMPP"` + TotalSpendable int64 `json:"totalSpendable"` // deprecated + TotalSpendableSat int64 `json:"totalSpendableSat"` + TotalSpendableMsat int64 `json:"totalSpendableMsat"` + TotalReceivable int64 `json:"totalReceivable"` // deprecated + TotalReceivableSat int64 `json:"totalReceivableSat"` + TotalReceivableMsat int64 `json:"totalReceivableMsat"` + NextMaxSpendable int64 `json:"nextMaxSpendable"` // deprecated + NextMaxSpendableSat int64 `json:"nextMaxSpendableSat"` + NextMaxSpendableMsat int64 `json:"nextMaxSpendableMsat"` + NextMaxReceivable int64 `json:"nextMaxReceivable"` // deprecated + NextMaxReceivableSat int64 `json:"nextMaxReceivableSat"` + NextMaxReceivableMsat int64 `json:"nextMaxReceivableMsat"` + NextMaxSpendableMPP int64 `json:"nextMaxSpendableMPP"` // deprecated + NextMaxSpendableMPPSat int64 `json:"nextMaxSpendableMPPSat"` + NextMaxSpendableMPPMsat int64 `json:"nextMaxSpendableMPPMsat"` + NextMaxReceivableMPP int64 `json:"nextMaxReceivableMPP"` // deprecated + NextMaxReceivableMPPSat int64 `json:"nextMaxReceivableMPPSat"` + NextMaxReceivableMPPMsat int64 `json:"nextMaxReceivableMPPMsat"` } type PayInvoiceResponse struct { diff --git a/lnclient/phoenixd/phoenixd.go b/lnclient/phoenixd/phoenixd.go index 94815388..86b12456 100644 --- a/lnclient/phoenixd/phoenixd.go +++ b/lnclient/phoenixd/phoenixd.go @@ -128,16 +128,18 @@ func (svc *PhoenixService) GetBalances(ctx context.Context, includeInactiveChann return &lnclient.BalancesResponse{ Onchain: lnclient.OnchainBalanceResponse{ - Spendable: 0, - Total: 0, - }, + PendingBalancesDetails: []lnclient.PendingBalanceDetails{}, + PendingSweepBalancesDetails: []lnclient.PendingBalanceDetails{}}, Lightning: lnclient.LightningBalanceResponse{ - TotalSpendable: balance, - TotalReceivable: 0, - NextMaxSpendable: balance, - NextMaxReceivable: 0, - NextMaxSpendableMPP: balance, - NextMaxReceivableMPP: 0, + TotalSpendable: balance, + TotalSpendableSat: balance / 1000, + TotalSpendableMsat: balance, + NextMaxSpendable: balance, + NextMaxSpendableSat: balance / 1000, + NextMaxSpendableMsat: balance, + NextMaxSpendableMPP: balance, + NextMaxSpendableMPPSat: balance / 1000, + NextMaxSpendableMPPMsat: balance, }, }, nil } diff --git a/nip47/controllers/get_balance_controller.go b/nip47/controllers/get_balance_controller.go index 155c5241..6ea93b2b 100644 --- a/nip47/controllers/get_balance_controller.go +++ b/nip47/controllers/get_balance_controller.go @@ -27,10 +27,10 @@ func (controller *nip47Controller) HandleGetBalanceEvent(ctx context.Context, ni "request_event_id": requestEventId, }).Debug("Getting balance") - balance := int64(0) + balanceMsat := int64(0) if app.Isolated { var err error - balance, err = queries.GetIsolatedBalance(controller.db, app.ID) + balanceMsat, err = queries.GetIsolatedBalanceMsat(controller.db, app.ID) if err != nil { logger.Logger.WithFields(logrus.Fields{ "request_event_id": requestEventId, @@ -53,11 +53,11 @@ func (controller *nip47Controller) HandleGetBalanceEvent(ctx context.Context, ni }, nostr.Tags{}) return } - balance = balances.Lightning.TotalSpendable + balanceMsat = balances.Lightning.TotalSpendable } responsePayload := &getBalanceResponse{ - Balance: balance, + Balance: balanceMsat, } // this is not part of the spec and does not seem to be used diff --git a/nip47/controllers/get_budget_controller.go b/nip47/controllers/get_budget_controller.go index 0238139e..16530ffb 100644 --- a/nip47/controllers/get_budget_controller.go +++ b/nip47/controllers/get_budget_controller.go @@ -28,8 +28,8 @@ func (controller *nip47Controller) HandleGetBudgetEvent(ctx context.Context, nip appPermission := db.AppPermission{} controller.db.Where("app_id = ? AND scope = ?", app.ID, models.PAY_INVOICE_METHOD).First(&appPermission) - maxAmount := appPermission.MaxAmountSat - if maxAmount == 0 { + maxAmountSat := appPermission.MaxAmountSat + if maxAmountSat == 0 { publishResponse(&models.Response{ ResultType: nip47Request.Method, Result: struct{}{}, @@ -37,7 +37,7 @@ func (controller *nip47Controller) HandleGetBudgetEvent(ctx context.Context, nip return } - usedBudget, err := queries.GetBudgetUsage(controller.db, &appPermission) + usedBudgetMsat, err := queries.GetBudgetUsageMsat(controller.db, &appPermission) if err != nil { logger.Logger.WithFields(logrus.Fields{ "request_event_id": requestEventId, @@ -50,8 +50,8 @@ func (controller *nip47Controller) HandleGetBudgetEvent(ctx context.Context, nip } responsePayload := &getBudgetResponse{ - TotalBudget: uint64(maxAmount * 1000), - UsedBudget: usedBudget, + TotalBudget: uint64(maxAmountSat * 1000), + UsedBudget: usedBudgetMsat, RenewalPeriod: appPermission.BudgetRenewal, RenewsAt: queries.GetBudgetRenewsAt(appPermission.BudgetRenewal), } diff --git a/tests/mock_ln_client.go b/tests/mock_ln_client.go index a2155b16..125b452e 100644 --- a/tests/mock_ln_client.go +++ b/tests/mock_ln_client.go @@ -29,7 +29,9 @@ var MockNodeInfo = lnclient.NodeInfo{ var MockLNClientBalances = lnclient.BalancesResponse{ Lightning: lnclient.LightningBalanceResponse{ - TotalSpendable: 21000, + TotalSpendable: 21000, + TotalSpendableSat: 21, + TotalSpendableMsat: 21000, }, } diff --git a/transactions/keysend_test.go b/transactions/keysend_test.go index 6e28149b..42f21d86 100644 --- a/transactions/keysend_test.go +++ b/transactions/keysend_test.go @@ -399,9 +399,9 @@ func TestSendKeysend_IsolatedAppToNoApp(t *testing.T) { result := svc.DB.Find(&transactions) assert.Equal(t, int64(3), result.RowsAffected) // expect balance to be decreased - balance, err := queries.GetIsolatedBalance(svc.DB, app.ID) + balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID) assert.NoError(t, err) - assert.Equal(t, int64(10000), balance) + assert.Equal(t, int64(10000), balanceMsat) } func TestSendKeysend_IsolatedAppToIsolatedApp(t *testing.T) { @@ -491,14 +491,14 @@ func TestSendKeysend_IsolatedAppToIsolatedApp(t *testing.T) { result := svc.DB.Find(&transactions) assert.Equal(t, int64(3), result.RowsAffected) // expect balance to be decreased - balance, err := queries.GetIsolatedBalance(svc.DB, app.ID) + balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID) assert.NoError(t, err) - assert.Equal(t, int64(10000), balance) + assert.Equal(t, int64(10000), balanceMsat) // expect app2 to receive the payment - balance, err = queries.GetIsolatedBalance(svc.DB, app2.ID) + balanceMsat, err = queries.GetIsolatedBalanceMsat(svc.DB, app2.ID) assert.NoError(t, err) - assert.Equal(t, int64(123000), balance) + assert.Equal(t, int64(123000), balanceMsat) // check notifications assert.Equal(t, 2, len(mockEventConsumer.GetConsumedEvents())) diff --git a/transactions/self_payments_test.go b/transactions/self_payments_test.go index 4e73eeb0..0754bea5 100644 --- a/transactions/self_payments_test.go +++ b/transactions/self_payments_test.go @@ -107,9 +107,9 @@ func TestSendPaymentSync_SelfPayment_NoAppToIsolatedApp(t *testing.T) { result := svc.DB.Find(&transactions) assert.Equal(t, int64(2), result.RowsAffected) // expect balance to be increased - balance, err := queries.GetIsolatedBalance(svc.DB, app.ID) + balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID) assert.NoError(t, err) - assert.Equal(t, int64(123000), balance) + assert.Equal(t, int64(123000), balanceMsat) } func TestSendPaymentSync_SelfPayment_NoAppToApp(t *testing.T) { @@ -232,9 +232,9 @@ func TestSendPaymentSync_SelfPayment_IsolatedAppToNoApp(t *testing.T) { result := svc.DB.Find(&transactions) assert.Equal(t, int64(3), result.RowsAffected) // expect balance to be decreased - balance, err := queries.GetIsolatedBalance(svc.DB, app.ID) + balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID) assert.NoError(t, err) - assert.Equal(t, int64(0), balance) + assert.Equal(t, int64(0), balanceMsat) } func TestSendPaymentSync_SelfPayment_IsolatedAppToApp(t *testing.T) { @@ -310,9 +310,9 @@ func TestSendPaymentSync_SelfPayment_IsolatedAppToApp(t *testing.T) { result := svc.DB.Find(&transactions) assert.Equal(t, int64(3), result.RowsAffected) // expect balance to be decreased - balance, err := queries.GetIsolatedBalance(svc.DB, app.ID) + balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID) assert.NoError(t, err) - assert.Equal(t, int64(0), balance) + assert.Equal(t, int64(0), balanceMsat) } func TestSendPaymentSync_SelfPayment_IsolatedAppToIsolatedApp(t *testing.T) { @@ -394,9 +394,9 @@ func TestSendPaymentSync_SelfPayment_IsolatedAppToIsolatedApp(t *testing.T) { result := svc.DB.Find(&transactions) assert.Equal(t, int64(3), result.RowsAffected) // expect balance to be decreased - balance, err := queries.GetIsolatedBalance(svc.DB, app.ID) + balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID) assert.NoError(t, err) - assert.Equal(t, int64(0), balance) + assert.Equal(t, int64(0), balanceMsat) // check notifications assert.Equal(t, 2, len(mockEventConsumer.GetConsumedEvents())) @@ -489,9 +489,9 @@ func TestSendPaymentSync_SelfPayment_IsolatedAppToSelf(t *testing.T) { assert.Equal(t, int64(3), result.RowsAffected) // expect balance to be unchanged - balance, err := queries.GetIsolatedBalance(svc.DB, app.ID) + balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID) assert.NoError(t, err) - assert.Equal(t, int64(123000), balance) + assert.Equal(t, int64(123000), balanceMsat) } func TestSendPaymentSync_SelfPayment_IsolatedAppToApp_AmountProvidedIgnoredOnNonZeroAmountInvoice(t *testing.T) { @@ -570,7 +570,7 @@ func TestSendPaymentSync_SelfPayment_IsolatedAppToApp_AmountProvidedIgnoredOnNon result := svc.DB.Find(&transactions) assert.Equal(t, int64(3), result.RowsAffected) // expect balance to be decreased - balance, err := queries.GetIsolatedBalance(svc.DB, app.ID) + balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID) assert.NoError(t, err) - assert.Equal(t, int64(0), balance) + assert.Equal(t, int64(0), balanceMsat) } diff --git a/transactions/transactions_service.go b/transactions/transactions_service.go index 06781565..76e83ce6 100644 --- a/transactions/transactions_service.go +++ b/transactions/transactions_service.go @@ -1090,14 +1090,14 @@ func (svc *transactionsService) validateCanPay(tx *gorm.DB, appId *uint, amount } if app.Isolated { - balance, err := queries.GetIsolatedBalance(tx, appPermission.AppId) + balanceMsat, err := queries.GetIsolatedBalanceMsat(tx, appPermission.AppId) if err != nil { return fmt.Errorf("failed to calculate isolated balance for app: %w", err) } - if int64(amountWithFeeReserve) > balance { + if int64(amountWithFeeReserve) > balanceMsat { logger.Logger.WithFields(logrus.Fields{ - "balance": balance, + "balance_msat": balanceMsat, "self_payment": selfPayment, "amount": amount, "amount_with_fee_reserve": amountWithFeeReserve, @@ -1120,11 +1120,11 @@ func (svc *transactionsService) validateCanPay(tx *gorm.DB, appId *uint, amount } if appPermission.MaxAmountSat > 0 { - budgetUsage, err := queries.GetBudgetUsage(tx, &appPermission) + budgetUsageMsat, err := queries.GetBudgetUsageMsat(tx, &appPermission) if err != nil { return fmt.Errorf("failed to calculate budget usage for app: %w", err) } - if int(amountWithFeeReserve/1000) > appPermission.MaxAmountSat-int(budgetUsage/1000) { + if int(amountWithFeeReserve/1000) > appPermission.MaxAmountSat-int(budgetUsageMsat/1000) { message := NewQuotaExceededError().Error() if description != "" { message += " " + description @@ -1477,12 +1477,12 @@ func (svc *transactionsService) checkBudgetUsage(app *db.App, dbTransaction *db. return } - budgetUsage, err := queries.GetBudgetUsage(gormTransaction, &appPermission) + budgetUsageMsat, err := queries.GetBudgetUsageMsat(gormTransaction, &appPermission) if err != nil { logger.Logger.WithField("app_id", dbTransaction.AppId).WithError(err).Error("failed to get budget usage") return } - budgetUsageSat := budgetUsage / 1000 + budgetUsageSat := budgetUsageMsat / 1000 warningUsage := uint64(math.Floor(float64(appPermission.MaxAmountSat) * 0.8)) if budgetUsageSat >= warningUsage && budgetUsageSat-dbTransaction.AmountMsat/1000 < warningUsage { svc.eventPublisher.Publish(&events.Event{