mirror of
https://github.com/lightninglabs/faraday.git
synced 2026-08-13 12:33:35 +02:00
Replaced "return err" cases with wrapped errors to attach the info which may be useful when debugging.
82 lines
2.4 KiB
Go
82 lines
2.4 KiB
Go
package accounting
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/btcsuite/btcd/btcutil"
|
|
"github.com/lightninglabs/faraday/fiat"
|
|
"github.com/lightninglabs/faraday/utils"
|
|
)
|
|
|
|
// fiatPrice is a function which gets the fiat price of bitcoin at a given time.
|
|
type fiatPrice func(timestamp time.Time) (*fiat.Price, error)
|
|
|
|
// satsToMsat converts an amount expressed in sats to msat.
|
|
func satsToMsat(sats btcutil.Amount) int64 {
|
|
return int64(sats) * 1000
|
|
}
|
|
|
|
// satsToMsat converts an amount expressed in sats to msat, flipping the
|
|
// sign on the value.
|
|
func invertedSatsToMsats(sats btcutil.Amount) int64 {
|
|
return satsToMsat(sats) * -1
|
|
}
|
|
|
|
// invertMsat flips the sign value of a msat value.
|
|
func invertMsat(msat int64) int64 {
|
|
return msat * -1
|
|
}
|
|
|
|
// getConversion is a helper function which queries coincap for a relevant set
|
|
// of price data and returns a convert function which can be used to get
|
|
// individual price points from this data.
|
|
func getConversion(ctx context.Context, startTime, endTime time.Time,
|
|
disableFiat bool, priceCfg *fiat.PriceSourceConfig) (fiatPrice, error) {
|
|
|
|
// If we don't want fiat values, just return a price which will yield
|
|
// a zero price and timestamp.
|
|
if disableFiat {
|
|
return func(_ time.Time) (*fiat.Price, error) {
|
|
return &fiat.Price{}, nil
|
|
}, nil
|
|
}
|
|
|
|
err := utils.ValidateTimeRange(startTime, endTime)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("conversion: invalid time range [%v,%v): %w",
|
|
startTime, endTime, err)
|
|
}
|
|
|
|
fiatClient, err := fiat.NewPriceSource(priceCfg)
|
|
if err != nil {
|
|
backend := "<nil>"
|
|
if priceCfg != nil {
|
|
backend = priceCfg.Backend.String()
|
|
}
|
|
return nil, fmt.Errorf("conversion: initialising price "+
|
|
"source backend %v failed: %w", backend, err)
|
|
}
|
|
|
|
// Get price data for our relevant period. We get pricing for the whole
|
|
// period rather than on a per-item level to limit the number of api
|
|
// calls we need to make to our external data source.
|
|
prices, err := fiatClient.GetPrices(ctx, startTime, endTime)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("conversion: fetching prices for "+
|
|
"range [%v,%v) failed: %w", startTime, endTime, err)
|
|
}
|
|
|
|
// Create a wrapper function which can be used to get individual price
|
|
// points from our set of price data as we create our report.
|
|
return func(ts time.Time) (*fiat.Price, error) {
|
|
price, err := fiat.GetPrice(prices, ts)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("conversion: fetching price "+
|
|
"at %v failed: %w", ts, err)
|
|
}
|
|
|
|
return price, nil
|
|
}, nil
|
|
}
|