Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,16 @@ func (api *api) RequestMempoolApi(ctx context.Context, endpoint string) (interfa
return nil, errors.New("failed to read response body")
}

if res.StatusCode != http.StatusOK {
logger.Logger.WithFields(logrus.Fields{
"endpoint": endpoint,
"url": url,
"status_code": res.StatusCode,
"body": string(body),
}).Error("Mempool endpoint returned non-success code")
return nil, fmt.Errorf("mempool endpoint returned non-success code: %s", string(body))
}

var jsonContent interface{}
jsonErr := json.Unmarshal(body, &jsonContent)
if jsonErr != nil {
Expand Down
10 changes: 10 additions & 0 deletions api/esplora.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ func (api *api) RequestEsploraApi(ctx context.Context, endpoint string) (interfa
return nil, errors.New("failed to read response body")
}

if res.StatusCode != http.StatusOK {
logger.Logger.WithFields(logrus.Fields{
"endpoint": endpoint,
"url": url,
"status_code": res.StatusCode,
"body": string(body),
}).Error("Esplora endpoint returned non-success code")
return nil, fmt.Errorf("esplora endpoint returned non-success code: %s", string(body))
}

var jsonContent interface{}
jsonErr := json.Unmarshal(body, &jsonContent)
if jsonErr != nil {
Expand Down
2 changes: 1 addition & 1 deletion api/rebalance.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (api *api) RebalanceChannel(ctx context.Context, rebalanceChannelRequest *R
return nil, errors.New("failed to read response body")
}

if res.StatusCode >= 300 {
if res.StatusCode != http.StatusOK {
logger.Logger.WithFields(logrus.Fields{
"request": newRspCreateOrderRequest,
"body": string(body),
Expand Down
53 changes: 27 additions & 26 deletions frontend/src/screens/internal-apps/ZapPlanner.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import useSWR from "swr";
import AppCard from "src/components/connections/AppCard";
import {
Card,
Expand Down Expand Up @@ -114,38 +115,38 @@ export function ZapPlanner() {
const [frequencyValue, setFrequencyValue] = React.useState("1");
const [frequencyUnit, setFrequencyUnit] = React.useState("months");
const [currency, setCurrency] = React.useState<string>("USD");
const [currencies, setCurrencies] = React.useState<string[]>([]);

const [convertedAmount, setConvertedAmount] = React.useState<string>("");
const [satoshiAmount, setSatoshiAmount] = React.useState<number | undefined>(
undefined
const { data: ratesData } = useSWR(
"https://getalby.com/api/rates",
(url: string) =>
fetch(url).then((res) => {
if (!res.ok) {
throw new Error(`Failed to load currencies: ${res.status}`);
}
return res.json() as Promise<
Record<string, { name: string; priority: number }>
>;
}),
{ onError: (err) => console.error("Failed to load currencies", err) }
);

React.useEffect(() => {
// fetch the fiat list and prepend sats/BTC
async function fetchCurrencies() {
try {
const res = await fetch("https://getalby.com/api/rates");
const data: Record<string, { name: string; priority: number }> =
await res.json();
const fiatCodes = Object.keys(data)
// drop "BTC" - ZapPlanner uses SATS for the bitcoin currency
const currencies = ratesData
? [
"SATS",
...Object.keys(ratesData)
.filter((code) => code !== "BTC")
.sort((a, b) => {
const priorityDiff = data[a].priority - data[b].priority;
if (priorityDiff !== 0) {
return priorityDiff;
}
return a.localeCompare(b);
const priorityDiff = ratesData[a].priority - ratesData[b].priority;
return priorityDiff !== 0 ? priorityDiff : a.localeCompare(b);
})
.map((c) => c.toUpperCase());
setCurrencies(["SATS", ...fiatCodes]);
} catch (err) {
console.error("Failed to load currencies", err);
}
}
fetchCurrencies();
}, []);
.map((c) => c.toUpperCase()),
]
: ["SATS"];

const [convertedAmount, setConvertedAmount] = React.useState<string>("");
const [satoshiAmount, setSatoshiAmount] = React.useState<number | undefined>(
undefined
);

React.useEffect(() => {
// reset form on close
Expand Down
50 changes: 26 additions & 24 deletions frontend/src/screens/settings/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { StarsIcon } from "lucide-react";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import Loading from "src/components/Loading";
import SettingsHeader from "src/components/SettingsHeader";
Expand Down Expand Up @@ -27,36 +26,39 @@ import { useInfo } from "src/hooks/useInfo";
import { cn } from "src/lib/utils";
import { handleRequestError } from "src/utils/handleRequestError";
import { request } from "src/utils/request";
import useSWR from "swr";

const albyRatesFetcher = (url: string) =>
fetch(url).then((res) => {
if (!res.ok) {
throw new Error(`Failed to fetch currencies: ${res.status}`);
}
return res.json() as Promise<Record<string, { name: string }>>;
});

function Settings() {
const { data: albyMe } = useAlbyMe();
const { theme, darkMode, setTheme, setDarkMode } = useTheme();

const [fiatCurrencies, setFiatCurrencies] = useState<[string, string][]>([]);

const { data: info, mutate: reloadInfo } = useInfo();

useEffect(() => {
async function fetchCurrencies() {
try {
const response = await fetch(`https://getalby.com/api/rates`);
const data: Record<string, { name: string }> = await response.json();

const mappedCurrencies: [string, string][] = Object.entries(data).map(
([code, details]) => [code.toUpperCase(), details.name]
);

mappedCurrencies.sort((a, b) => a[1].localeCompare(b[1]));

setFiatCurrencies(mappedCurrencies);
} catch (error) {
console.error(error);
handleRequestError("Failed to fetch currencies", error);
}
const { data: ratesData } = useSWR(
"https://getalby.com/api/rates",
albyRatesFetcher,
{
onError: (error) =>
handleRequestError("Failed to fetch currencies", error),
}
);

fetchCurrencies();
}, []);
const fiatCurrencies: [string, string][] = ratesData
? Object.entries(ratesData)
.map(([code, details]): [string, string] => [
code.toUpperCase(),
details.name,
])
.sort((a, b) => a[1].localeCompare(b[1]))
: [];

const { data: info, mutate: reloadInfo } = useInfo();

async function updateSettings(
payload: Record<string, string | boolean>,
Expand Down
62 changes: 56 additions & 6 deletions lnclient/phoenixd/phoenixd.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
b64 "encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"strconv"
Expand Down Expand Up @@ -105,8 +107,16 @@ func (svc *PhoenixService) GetBalances(ctx context.Context, includeInactiveChann
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("phoenixd /getbalance returned non-success status: %d %s", resp.StatusCode, string(body))
}

var balanceRes BalanceResponse
if err := json.NewDecoder(resp.Body).Decode(&balanceRes); err != nil {
if err := json.Unmarshal(body, &balanceRes); err != nil {
return nil, err
}

Expand Down Expand Up @@ -145,8 +155,16 @@ func fetchNodeInfo(ctx context.Context, svc *PhoenixService) (info *lnclient.Nod
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("phoenixd /getinfo returned non-success status: %d %s", resp.StatusCode, string(body))
}

var infoRes InfoResponse
if err := json.NewDecoder(resp.Body).Decode(&infoRes); err != nil {
if err := json.Unmarshal(body, &infoRes); err != nil {
return nil, err
}
return &lnclient.NodeInfo{
Expand Down Expand Up @@ -199,8 +217,16 @@ func (svc *PhoenixService) MakeInvoice(ctx context.Context, amount int64, descri
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("phoenixd /createinvoice returned non-success status: %d %s", resp.StatusCode, string(body))
}

var invoiceRes MakeInvoiceResponse
if err := json.NewDecoder(resp.Body).Decode(&invoiceRes); err != nil {
if err := json.Unmarshal(body, &invoiceRes); err != nil {
return nil, err
}

Expand Down Expand Up @@ -238,8 +264,16 @@ func (svc *PhoenixService) LookupInvoice(ctx context.Context, paymentHash string
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("phoenixd /payments/incoming returned non-success status: %d %s", resp.StatusCode, string(body))
}

var invoiceRes InvoiceResponse
if err := json.NewDecoder(resp.Body).Decode(&invoiceRes); err != nil {
if err := json.Unmarshal(body, &invoiceRes); err != nil {
return nil, err
}

Expand Down Expand Up @@ -271,8 +305,16 @@ func (svc *PhoenixService) SendPaymentSync(payReq string, amount *uint64) (*lncl
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("phoenixd /payinvoice returned non-success status: %d %s", resp.StatusCode, string(body))
}

var payRes PayResponse
if err := json.NewDecoder(resp.Body).Decode(&payRes); err != nil {
if err := json.Unmarshal(body, &payRes); err != nil {
return nil, err
}

Expand Down Expand Up @@ -312,8 +354,16 @@ func (svc *PhoenixService) GetNodeConnectionInfo(ctx context.Context) (nodeConne
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("phoenixd /getinfo returned non-success status: %d %s", resp.StatusCode, string(body))
}

var infoRes InfoResponse
if err := json.NewDecoder(resp.Body).Decode(&infoRes); err != nil {
if err := json.Unmarshal(body, &infoRes); err != nil {
return nil, err
}
return &lnclient.NodeConnectionInfo{
Expand Down
30 changes: 30 additions & 0 deletions swaps/swaps_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -1393,6 +1393,21 @@ func (svc *swapsService) doMempoolRequest(endpoint string, result interface{}) e
return errors.New("failed to read response body")
}

if res.StatusCode != http.StatusOK {
logger.Logger.WithFields(logrus.Fields{
"component": "swaps",
"endpoint": endpoint,
"url": url,
"status_code": res.StatusCode,
"body": string(body),
}).Error("Swaps mempool API endpoint returned non-success code")
return fmt.Errorf(
"swaps mempool API endpoint returned non-success code for %s: %s",
endpoint,
string(body),
)
}

jsonErr := json.Unmarshal(body, &result)
if jsonErr != nil {
logger.Logger.WithError(jsonErr).WithFields(logrus.Fields{
Expand Down Expand Up @@ -1530,6 +1545,21 @@ func (svc *swapsService) getNextUnusedAddressFromXpub() (string, error) {
return nil, err
}

if res.StatusCode != http.StatusOK {
logger.Logger.WithFields(logrus.Fields{
"component": "swaps",
"endpoint": endpoint,
"url": url,
"status_code": res.StatusCode,
"body": string(body),
}).Error("Swaps esplora endpoint returned non-success code")
return nil, fmt.Errorf(
"swaps esplora endpoint returned non-success code for %s: %s",
endpoint,
string(body),
)
}

var jsonContent interface{}
err = json.Unmarshal(body, &jsonContent)
if err != nil {
Expand Down
Loading