mirror of
https://github.com/aljazceru/lspd.git
synced 2025-12-18 22:34:22 +01:00
add a mempool client for fee estimation
This commit is contained in:
21
chain/fee_estimator.go
Normal file
21
chain/fee_estimator.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package chain
|
||||
|
||||
import "context"
|
||||
|
||||
type FeeStrategy int
|
||||
|
||||
const (
|
||||
FeeStrategyFastest FeeStrategy = 0
|
||||
FeeStrategyHalfHour FeeStrategy = 1
|
||||
FeeStrategyHour FeeStrategy = 2
|
||||
FeeStrategyEconomy FeeStrategy = 3
|
||||
FeeStrategyMinimum FeeStrategy = 4
|
||||
)
|
||||
|
||||
type FeeEstimation struct {
|
||||
SatPerVByte float64
|
||||
}
|
||||
|
||||
type FeeEstimator interface {
|
||||
EstimateFeeRate(context.Context, FeeStrategy) (*FeeEstimation, error)
|
||||
}
|
||||
90
mempool/mempool_client.go
Normal file
90
mempool/mempool_client.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package mempool
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/breez/lspd/chain"
|
||||
)
|
||||
|
||||
type MempoolClient struct {
|
||||
apiBaseUrl string
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
type RecommendedFeesResponse struct {
|
||||
FastestFee float64 `json:"fastestFee"`
|
||||
HalfHourFee float64 `json:"halfHourFee"`
|
||||
HourFee float64 `json:"hourFee"`
|
||||
EconomyFee float64 `json:"economyFee"`
|
||||
MinimumFee float64 `json:"minimumFee"`
|
||||
}
|
||||
|
||||
func NewMempoolClient(apiBaseUrl string) (*MempoolClient, error) {
|
||||
if apiBaseUrl == "" {
|
||||
return nil, fmt.Errorf("apiBaseUrl not set")
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(apiBaseUrl, "/") {
|
||||
apiBaseUrl = apiBaseUrl + "/"
|
||||
}
|
||||
|
||||
return &MempoolClient{
|
||||
apiBaseUrl: apiBaseUrl,
|
||||
httpClient: http.DefaultClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *MempoolClient) EstimateFeeRate(
|
||||
ctx context.Context,
|
||||
strategy chain.FeeStrategy,
|
||||
) (*chain.FeeEstimation, error) {
|
||||
req, err := http.NewRequestWithContext(
|
||||
ctx,
|
||||
"GET",
|
||||
m.apiBaseUrl+"fees/recommended",
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("http.NewRequestWithContext error: %w", err)
|
||||
}
|
||||
|
||||
resp, err := m.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("httpClient.Do error: %w", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
if !(resp.StatusCode >= 200 && resp.StatusCode < 300) {
|
||||
return nil, fmt.Errorf("error statuscode %v: %w", resp.StatusCode, err)
|
||||
}
|
||||
|
||||
var body RecommendedFeesResponse
|
||||
err = json.NewDecoder(resp.Body).Decode(&body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
|
||||
}
|
||||
|
||||
var rate float64
|
||||
switch strategy {
|
||||
case chain.FeeStrategyFastest:
|
||||
rate = body.FastestFee
|
||||
case chain.FeeStrategyHalfHour:
|
||||
rate = body.HalfHourFee
|
||||
case chain.FeeStrategyHour:
|
||||
rate = body.HourFee
|
||||
case chain.FeeStrategyEconomy:
|
||||
rate = body.EconomyFee
|
||||
case chain.FeeStrategyMinimum:
|
||||
rate = body.MinimumFee
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported fee strategy: %v", strategy)
|
||||
}
|
||||
|
||||
return &chain.FeeEstimation{
|
||||
SatPerVByte: rate,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user