From 71dbbe44dd58e02216473b8372c0d067ef76a39f Mon Sep 17 00:00:00 2001 From: Shroominic Date: Sun, 17 Aug 2025 16:57:39 -0300 Subject: [PATCH 1/5] change /models to include_in_schema=False --- routstr/payment/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routstr/payment/models.py b/routstr/payment/models.py index 1ad0f644..48dce0f8 100644 --- a/routstr/payment/models.py +++ b/routstr/payment/models.py @@ -176,6 +176,6 @@ async def update_sats_pricing() -> None: @models_router.get("/v1/models") -@models_router.get("/models") +@models_router.get("/models", include_in_schema=False) async def models() -> dict: return {"data": MODELS} From cf24cefc1fe9b0ff254114638f9265e081e4d45a Mon Sep 17 00:00:00 2001 From: Shroominic Date: Sun, 17 Aug 2025 16:59:06 -0300 Subject: [PATCH 2/5] fix msat/sat balance indicator --- routstr/balance.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/routstr/balance.py b/routstr/balance.py index 68e5ab2e..9e3063b7 100644 --- a/routstr/balance.py +++ b/routstr/balance.py @@ -85,7 +85,7 @@ async def refund_wallet_endpoint( key.refund_mint_url or PRIMARY_MINT_URL, key.refund_address, ) - result = {"recipient": key.refund_address, "msats": remaining_balance_msats} + result = {"recipient": key.refund_address} else: refund_amount = ( remaining_balance_msats // 1000 @@ -96,12 +96,13 @@ async def refund_wallet_endpoint( token = await send_token( refund_amount, refund_currency, key.refund_mint_url ) + result = {"token": token} + + if key.refund_currency == "sat": + result["sats"] = str(remaining_balance_msats // 1000) + else: + result["msats"] = str(remaining_balance_msats) - result = { - "msats": remaining_balance_msats, - "recipient": None, - "token": token, - } except HTTPException: # Re-raise HTTP exceptions (like 400 for balance too small) raise From 97cdc0dbcd4832152eefd060681ddad24f98a866 Mon Sep 17 00:00:00 2001 From: Shroominic Date: Sun, 17 Aug 2025 16:59:21 -0300 Subject: [PATCH 3/5] fix msat balance convertsion --- routstr/wallet.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/routstr/wallet.py b/routstr/wallet.py index 83acbdba..4543ce35 100644 --- a/routstr/wallet.py +++ b/routstr/wallet.py @@ -234,6 +234,8 @@ async def fetch_all_balances( ) proofs = await slow_filter_spend_proofs(proofs, wallet) user_balance = await db.balances_for_mint_and_unit(session, mint_url, unit) + if unit == "sat": + user_balance = user_balance // 1000 proofs_balance = sum(proof.amount for proof in proofs) result: BalanceDetail = { @@ -317,12 +319,14 @@ async def periodic_payout() -> None: user_balance = await db.balances_for_mint_and_unit( session, mint_url, unit ) + if unit == "sat": + user_balance = user_balance // 1000 proofs_balance = sum(proof.amount for proof in proofs) available_balance = proofs_balance - user_balance print(f"Balance: {proofs_balance} {unit}") print(f"User balance: {user_balance} {unit}") print(f"Available balance: {available_balance} {unit}") - min_amount = 5 if unit == "sat" else 5000 + min_amount = 210 if unit == "sat" else 210000 if proofs_balance > min_amount: amount_received = await raw_send_to_lnurl( wallet, proofs, RECEIVE_LN_ADDRESS, unit From 56cc14928ca9f26c2a2b53fa5a32049806ec0d1f Mon Sep 17 00:00:00 2001 From: Shroominic Date: Sun, 17 Aug 2025 17:08:40 -0300 Subject: [PATCH 4/5] fix tests --- tests/integration/test_example.py | 10 ++++++- tests/integration/test_wallet_refund.py | 35 ++++++++++++++++++------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/tests/integration/test_example.py b/tests/integration/test_example.py index e4c025ac..6ec006aa 100644 --- a/tests/integration/test_example.py +++ b/tests/integration/test_example.py @@ -105,7 +105,15 @@ async def test_full_wallet_flow( assert refund_response.status_code == 200 refund_data = refund_response.json() assert "token" in refund_data - assert refund_data["msats"] == (initial_amount + topup_amount) * 1000 + + # Check for either sats or msats depending on refund_currency + total_amount = initial_amount + topup_amount + if "sats" in refund_data: + assert refund_data["sats"] == str(total_amount) + elif "msats" in refund_data: + assert refund_data["msats"] == str(total_amount * 1000) + else: + pytest.fail("Response should contain either 'sats' or 'msats'") @pytest.mark.integration diff --git a/tests/integration/test_wallet_refund.py b/tests/integration/test_wallet_refund.py index 9cbf2a76..d68b5197 100644 --- a/tests/integration/test_wallet_refund.py +++ b/tests/integration/test_wallet_refund.py @@ -41,13 +41,17 @@ async def test_full_balance_refund_returns_cashu_token( assert response.status_code == 200 data = response.json() - # Should return msats, recipient (None), and token - assert "msats" in data - assert "recipient" in data + # Should return either sats or msats (as string), and token assert "token" in data - assert data["msats"] == initial_balance - assert data["recipient"] is None assert data["token"].startswith("cashuA") + + # Check for either sats or msats depending on refund_currency + if "sats" in data: + assert data["sats"] == str(initial_balance // 1000) # Convert msats to sats + elif "msats" in data: + assert data["msats"] == str(initial_balance) + else: + pytest.fail("Response should contain either 'sats' or 'msats'") # Validate token format token = data["token"] @@ -88,7 +92,14 @@ async def test_partial_refund_not_supported( # Should still refund full balance (endpoint ignores the parameter) assert response.status_code == 200 data = response.json() - assert data["msats"] == 10_000_000 # Full balance + + # Check for either sats or msats + if "sats" in data: + assert data["sats"] == "10000" # Full balance in sats + elif "msats" in data: + assert data["msats"] == "10000000" # Full balance in msats + else: + pytest.fail("Response should contain either 'sats' or 'msats'") @pytest.mark.integration @@ -432,12 +443,16 @@ async def test_refund_response_format( data = response.json() assert isinstance(data, dict) - assert "msats" in data - assert "recipient" in data assert "token" in data - assert isinstance(data["msats"], int) - assert data["recipient"] is None assert isinstance(data["token"], str) + + # Should have either sats or msats (both as strings) + if "sats" in data: + assert isinstance(data["sats"], str) + elif "msats" in data: + assert isinstance(data["msats"], str) + else: + pytest.fail("Response should contain either 'sats' or 'msats'") # Test 2: Test with refund address would require creating key via proxy endpoint # Since refund address headers only work on proxy endpoints, not wallet endpoints From 7fce5318b6835e9d63713997b480582cc11af124 Mon Sep 17 00:00:00 2001 From: Shroominic Date: Sun, 17 Aug 2025 17:09:17 -0300 Subject: [PATCH 5/5] fmt --- tests/integration/test_example.py | 2 +- tests/integration/test_wallet_refund.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/integration/test_example.py b/tests/integration/test_example.py index 6ec006aa..6657517c 100644 --- a/tests/integration/test_example.py +++ b/tests/integration/test_example.py @@ -105,7 +105,7 @@ async def test_full_wallet_flow( assert refund_response.status_code == 200 refund_data = refund_response.json() assert "token" in refund_data - + # Check for either sats or msats depending on refund_currency total_amount = initial_amount + topup_amount if "sats" in refund_data: diff --git a/tests/integration/test_wallet_refund.py b/tests/integration/test_wallet_refund.py index d68b5197..c2461cae 100644 --- a/tests/integration/test_wallet_refund.py +++ b/tests/integration/test_wallet_refund.py @@ -44,7 +44,7 @@ async def test_full_balance_refund_returns_cashu_token( # Should return either sats or msats (as string), and token assert "token" in data assert data["token"].startswith("cashuA") - + # Check for either sats or msats depending on refund_currency if "sats" in data: assert data["sats"] == str(initial_balance // 1000) # Convert msats to sats @@ -92,7 +92,7 @@ async def test_partial_refund_not_supported( # Should still refund full balance (endpoint ignores the parameter) assert response.status_code == 200 data = response.json() - + # Check for either sats or msats if "sats" in data: assert data["sats"] == "10000" # Full balance in sats @@ -445,7 +445,7 @@ async def test_refund_response_format( assert isinstance(data, dict) assert "token" in data assert isinstance(data["token"], str) - + # Should have either sats or msats (both as strings) if "sats" in data: assert isinstance(data["sats"], str)