mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-10-05 20:28:23 +00:00
Removes the child-key (shared parent balance) feature and the balance-limit machinery from the entire stack: Backend: - Drop POST /v1/balance/child-key and /v1/balance/child-key/reset - Remove parent-key billing indirection (get_billing_key); every key is charged directly - Remove balance_limit/balance_limit_reset enforcement, reset policies, and the periodic limit-reset background task - Remove child-key guards on refund/history endpoints - Remove child_key_cost setting and /v1/info child_key_cost_msats - Remove balance_limit fields from LightningInvoice model and invoice-creation API - Admin balances API returns plain sums (no parent/child split) Migration (e5a6b7c8d9f0): - Nulls parent_key_hash on children (they become standalone keys; parents keep 100% of their balance, so no funds are lost) - Drops parent_key_hash + balance_limit columns from api_keys and balance_limit columns from lightning_invoices - Verified: upgrade, downgrade, and fund preservation round-trip UI: - Remove child-key creator, child key panels, balance-limit inputs - Key options now offer validity date only - Temporary balances table renders all keys uniformly Tests: child-key suites removed; remaining suites converted to single-key semantics (441 integration + 1313 unit tests pass). Docs updated accordingly.
44 lines
1.4 KiB
Python
44 lines
1.4 KiB
Python
import time
|
|
|
|
import pytest
|
|
from sqlmodel.ext.asyncio.session import AsyncSession
|
|
|
|
from routstr.auth import pay_for_request
|
|
from routstr.core.db import ApiKey
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_key_validity_date(integration_session: AsyncSession) -> None:
|
|
# 1. Create a key that is expired
|
|
expired_time = int(time.time()) - 3600
|
|
key = ApiKey(hashed_key="expired_key", balance=1000, validity_date=expired_time)
|
|
integration_session.add(key)
|
|
await integration_session.commit()
|
|
|
|
# 2. Try to pay for a request - should fail
|
|
with pytest.raises(Exception) as excinfo:
|
|
await pay_for_request(key, 100, integration_session)
|
|
assert "expired" in str(excinfo.value).lower()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_refund_does_not_delete_key(integration_session: AsyncSession) -> None:
|
|
# This requires mocking the router call or testing the logic in balance.py
|
|
from routstr.balance import ApiKey
|
|
|
|
key = ApiKey(hashed_key="refund_test_key", balance=1000, reserved_balance=100)
|
|
integration_session.add(key)
|
|
await integration_session.commit()
|
|
|
|
# Logic from refund_wallet_endpoint:
|
|
key.balance = 0
|
|
key.reserved_balance = 0
|
|
integration_session.add(key)
|
|
await integration_session.commit()
|
|
|
|
# Verify key still exists
|
|
fetched_key = await integration_session.get(ApiKey, "refund_test_key")
|
|
assert fetched_key is not None
|
|
assert fetched_key.balance == 0
|
|
assert fetched_key.reserved_balance == 0
|