Compare commits
3 commits
v1.1.1-aio
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| a91527183b | |||
| 9a9539224c | |||
| 8dfd3feba8 |
3 changed files with 19 additions and 18 deletions
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Bolt Cards",
|
||||
"short_description": "Self custody Bolt Cards with one time LNURLw",
|
||||
"tile": "/boltcards/static/image/boltcard.png",
|
||||
"version": "1.1.1-aio.3",
|
||||
"version": "1.1.1-aio.4",
|
||||
"min_lnbits_version": "1.3.0",
|
||||
"contributors": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -106,16 +106,16 @@ def stubs(monkeypatch):
|
|||
async def get_wallet(wallet_id):
|
||||
return state["wallet"]
|
||||
|
||||
async def satoshis_amount_as_fiat(amount, currency):
|
||||
assert currency == "USD"
|
||||
return amount * 0.0008 # 123456 sats → 98.7648
|
||||
def cache_get(key, default=None):
|
||||
# A warm LNbits rate cache: 1 BTC = 80,000 USD → 123456 sats = 98.7648
|
||||
return 80_000.0 if key == "btc-price-USD" else default
|
||||
|
||||
monkeypatch.setattr(v, "get_card_by_external_id", get_card_by_external_id)
|
||||
monkeypatch.setattr(v, "update_card_counter", update_card_counter)
|
||||
monkeypatch.setattr(v, "get_hits_today", get_hits_today)
|
||||
monkeypatch.setattr(v, "create_hit", create_hit)
|
||||
monkeypatch.setattr(v, "get_wallet", get_wallet)
|
||||
monkeypatch.setattr(v, "satoshis_amount_as_fiat", satoshis_amount_as_fiat)
|
||||
monkeypatch.setattr(v.cache, "get", cache_get)
|
||||
monkeypatch.setattr(
|
||||
v.settings, "lnbits_default_accounting_currency", state["default_currency"]
|
||||
)
|
||||
|
|
@ -209,18 +209,18 @@ async def test_session_falls_back_to_instance_default_currency(stubs, monkeypatc
|
|||
p, c = make_sun(counter=6)
|
||||
out = await v.api_session(p, c, FakeRequest(), "ext123")
|
||||
assert out["currency"] == "USD"
|
||||
assert out["fiat"] == pytest.approx(5 * 0.0008)
|
||||
assert out["fiat"] == pytest.approx(5 / 100_000_000 * 80_000)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_session_survives_rate_failure(stubs, monkeypatch):
|
||||
async def boom(amount, currency):
|
||||
raise ValueError("no rate")
|
||||
|
||||
monkeypatch.setattr(v, "satoshis_amount_as_fiat", boom)
|
||||
async def test_session_leaves_fiat_null_on_a_cold_rate_cache(stubs, monkeypatch):
|
||||
# No external rate lookup ever happens on the unlock path: a cache miss
|
||||
# simply means the terminal prices the balance itself.
|
||||
monkeypatch.setattr(v.cache, "get", lambda key, default=None: default)
|
||||
p, c = make_sun(counter=6)
|
||||
out = await v.api_session(p, c, FakeRequest(), "ext123")
|
||||
assert out["authenticated"] is True
|
||||
assert out["currency"] == "USD"
|
||||
assert out["fiat"] is None
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from fastapi import APIRouter, HTTPException, Query, Request
|
|||
from lnbits.core.crud import get_wallet
|
||||
from lnbits.core.services import create_invoice, pay_invoice
|
||||
from lnbits.settings import settings
|
||||
from lnbits.utils.exchange_rates import satoshis_amount_as_fiat
|
||||
from lnbits.utils.cache import cache
|
||||
from lnurl import (
|
||||
CallbackUrl,
|
||||
LightningInvoice,
|
||||
|
|
@ -507,8 +507,10 @@ async def api_session(p, c, request: Request, external_id: str):
|
|||
|
||||
# Balance + fiat, the way the LNbits wallet page shows them: the wallet's
|
||||
# own currency first (per-wallet setting, LNbits ≥ 1.6), then the
|
||||
# instance's default accounting currency; no currency → no fiat, and a
|
||||
# rate failure never fails the session.
|
||||
# instance's default accounting currency. The fiat figure comes ONLY from
|
||||
# LNbits' already-warm rate cache: this response gates the terminal
|
||||
# unlocking, and a cold lookup queries external exchanges (~1 s). Cache
|
||||
# miss → `fiat: null`; the terminal prices the sats itself.
|
||||
wallet = await get_wallet(card.wallet)
|
||||
balance_msat = int(wallet.balance_msat) if wallet else 0
|
||||
currency = (getattr(wallet, "currency", None) if wallet else None) or getattr(
|
||||
|
|
@ -516,10 +518,9 @@ async def api_session(p, c, request: Request, external_id: str):
|
|||
)
|
||||
fiat = None
|
||||
if currency:
|
||||
try:
|
||||
fiat = await satoshis_amount_as_fiat(balance_msat / 1000, currency)
|
||||
except Exception:
|
||||
fiat = None
|
||||
price = cache.get(f"btc-price-{currency}") # fiat per BTC, as btc_price()
|
||||
if isinstance(price, (int, float)) and price > 0:
|
||||
fiat = balance_msat / 1000 / 100_000_000 * float(price)
|
||||
|
||||
return {
|
||||
"authenticated": True,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue