diff --git a/internal/api/analytics.go b/internal/api/analytics.go index 58792d9e..ee0e1c2c 100644 --- a/internal/api/analytics.go +++ b/internal/api/analytics.go @@ -272,7 +272,7 @@ func (s Service) GetTransactionAnalytics(w http.ResponseWriter, r *http.Request) Fee: payment.Fee, FeeSats: payment.Fee / 1000, Memo: payment.Memo, - Time: payment.Time, + Time: int(payment.Time), Timestamp: paymentTime.Format(time.RFC3339), PaymentType: paymentType, Bolt11: payment.Bolt11, @@ -443,7 +443,7 @@ func (s Service) GetUserTransactionHistory(w http.ResponseWriter, r *http.Reques Fee: payment.Fee, FeeSats: payment.Fee / 1000, Memo: payment.Memo, - Time: payment.Time, + Time: int(payment.Time), Timestamp: paymentTime.Format(time.RFC3339), PaymentType: paymentType, Bolt11: payment.Bolt11, diff --git a/internal/lnbits/types.go b/internal/lnbits/types.go index 6cdb15e3..3ded6c4d 100644 --- a/internal/lnbits/types.go +++ b/internal/lnbits/types.go @@ -3,6 +3,7 @@ package lnbits import ( "crypto/sha256" "encoding/hex" + "encoding/json" "fmt" "time" @@ -142,13 +143,44 @@ type Wallet struct { User string `json:"user"` } +// UnixTime is a payment timestamp in unix seconds. lnbits 0.x serialises +// `time` as a number, 1.x as an RFC3339 string, so decoding accepts either and +// normalises to seconds. Encoding always emits the number, keeping the API +// responses this type is serialised into unchanged. +type UnixTime int64 + +func (t *UnixTime) UnmarshalJSON(b []byte) error { + s := string(b) + if s == "null" || s == `""` { + return nil + } + if b[0] != '"' { + var n int64 + if err := json.Unmarshal(b, &n); err != nil { + return err + } + *t = UnixTime(n) + return nil + } + var str string + if err := json.Unmarshal(b, &str); err != nil { + return err + } + parsed, err := time.Parse(time.RFC3339, str) + if err != nil { + return fmt.Errorf("lnbits: unrecognised payment time %q: %w", str, err) + } + *t = UnixTime(parsed.Unix()) + return nil +} + type Payment struct { CheckingID string `json:"checking_id"` Pending bool `json:"pending"` Amount int64 `json:"amount"` Fee int64 `json:"fee"` Memo string `json:"memo"` - Time int `json:"time"` + Time UnixTime `json:"time"` Bolt11 string `json:"bolt11"` Preimage string `json:"preimage"` PaymentHash string `json:"payment_hash"` diff --git a/internal/lnbits/webhook/webhook.go b/internal/lnbits/webhook/webhook.go index 4b457ad3..2030e2e4 100644 --- a/internal/lnbits/webhook/webhook.go +++ b/internal/lnbits/webhook/webhook.go @@ -33,19 +33,19 @@ type Server struct { } type Webhook struct { - CheckingID string `json:"checking_id"` - Pending bool `json:"pending"` - Amount int64 `json:"amount"` - Fee int64 `json:"fee"` - Memo string `json:"memo"` - Time int64 `json:"time"` - Bolt11 string `json:"bolt11"` - Preimage string `json:"preimage"` - PaymentHash string `json:"payment_hash"` - Extra struct{} `json:"extra"` - WalletID string `json:"wallet_id"` - Webhook string `json:"webhook"` - WebhookStatus interface{} `json:"webhook_status"` + CheckingID string `json:"checking_id"` + Pending bool `json:"pending"` + Amount int64 `json:"amount"` + Fee int64 `json:"fee"` + Memo string `json:"memo"` + Time lnbits.UnixTime `json:"time"` + Bolt11 string `json:"bolt11"` + Preimage string `json:"preimage"` + PaymentHash string `json:"payment_hash"` + Extra struct{} `json:"extra"` + WalletID string `json:"wallet_id"` + Webhook string `json:"webhook"` + WebhookStatus interface{} `json:"webhook_status"` } func NewServer(bot *telegram.TipBot) *Server {