diff --git a/lnbits/core/models.py b/lnbits/core/models.py index 0829709c9..4afca23bc 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -12,12 +12,13 @@ from typing import Callable, Optional from ecdsa import SECP256k1, SigningKey from fastapi import Query -from pydantic import BaseModel +from pydantic import BaseModel, validator from lnbits.db import FilterModel, FromRowModel from lnbits.helpers import url_for from lnbits.lnurl import encode as lnurl_encode from lnbits.settings import settings +from lnbits.utils.exchange_rates import allowed_currencies from lnbits.wallets import get_funding_source from lnbits.wallets.base import ( PaymentPendingStatus, @@ -382,6 +383,14 @@ class CreateInvoice(BaseModel): bolt11: Optional[str] = None lnurl_callback: Optional[str] = None + @validator("unit") + @classmethod + def unit_is_from_allowed_currencies(cls, v): + if v != "sat" and v not in allowed_currencies(): + raise ValueError("The provided unit is not supported") + + return v + class CreateTopup(BaseModel): id: str diff --git a/tests/api/test_api.py b/tests/api/test_api.py index 26020b9e1..7c5b5a3ec 100644 --- a/tests/api/test_api.py +++ b/tests/api/test_api.py @@ -150,6 +150,21 @@ async def test_create_invoice_fiat_amount(client, inkey_headers_to): assert extra["fiat_rate"] +@pytest.mark.asyncio +@pytest.mark.parametrize("currency", ("msat", "RRR")) +async def test_create_invoice_validates_used_currency( + currency, client, inkey_headers_to +): + data = await get_random_invoice_data() + data["unit"] = currency + response = await client.post( + "/api/v1/payments", json=data, headers=inkey_headers_to + ) + assert response.status_code == 400 + res_data = response.json() + assert "The provided unit is not supported" in res_data["detail"] + + # check POST /api/v1/payments: invoice creation for internal payments only @pytest.mark.asyncio async def test_create_internal_invoice(client, inkey_headers_to):