* wip

* wip

* model

* refactor wallet transactions

* refactor wallet

* sending with fees works and outputs fill up the wallet

* wip work

* ok

* comments

* receive with amount=0

* correctly import postmeltrequest

* fix melt amount

* tests working

* remove mint_loaded decorator in deprecated wallet api

* wallet works with units

* refactor: melt_quote

* fix fees

* add file

* fees for melt inputs

* set default input fee for internal quotes to 0

* fix coinselect

* coin selection working

* yo

* fix all tests

* clean up

* last commit added fees for inputs for melt transactions - this commit adds a blanace too low exception

* fix fee return and melt quote max allowed amount check during creation of melt quote

* clean up code

* add tests for fees

* add melt tests

* update wallet fee information
This commit is contained in:
callebtc
2024-06-15 16:22:41 +02:00
committed by GitHub
parent d80280e35d
commit d30b1a2777
47 changed files with 2446 additions and 1554 deletions

View File

@@ -45,6 +45,7 @@ settings.mint_private_key = "TEST_PRIVATE_KEY"
settings.mint_seed_decryption_key = ""
settings.mint_max_balance = 0
settings.mint_lnd_enable_mpp = True
settings.mint_input_fee_ppk = 0
assert "test" in settings.cashu_dir
shutil.rmtree(settings.cashu_dir, ignore_errors=True)

View File

@@ -2,9 +2,10 @@ from typing import List
import pytest
from cashu.core.base import BlindedMessage, PostMintQuoteRequest, Proof
from cashu.core.base import BlindedMessage, Proof
from cashu.core.crypto.b_dhke import step1_alice
from cashu.core.helpers import calculate_number_of_blank_outputs
from cashu.core.models import PostMintQuoteRequest
from cashu.core.settings import settings
from cashu.mint.ledger import Ledger
from tests.helpers import pay_if_regtest
@@ -129,9 +130,9 @@ async def test_generate_promises(ledger: Ledger):
async def test_generate_change_promises(ledger: Ledger):
# Example slightly adapted from NUT-08 because we want to ensure the dynamic change
# token amount works: `n_blank_outputs != n_returned_promises != 4`.
invoice_amount = 100_000
# invoice_amount = 100_000
fee_reserve = 2_000
total_provided = invoice_amount + fee_reserve
# total_provided = invoice_amount + fee_reserve
actual_fee = 100
expected_returned_promises = 7 # Amounts = [4, 8, 32, 64, 256, 512, 1024]
@@ -149,7 +150,7 @@ async def test_generate_change_promises(ledger: Ledger):
]
promises = await ledger._generate_change_promises(
total_provided, invoice_amount, actual_fee, outputs
fee_provided=fee_reserve, fee_paid=actual_fee, outputs=outputs
)
assert len(promises) == expected_returned_promises
@@ -160,9 +161,9 @@ async def test_generate_change_promises(ledger: Ledger):
async def test_generate_change_promises_legacy_wallet(ledger: Ledger):
# Check if mint handles a legacy wallet implementation (always sends 4 blank
# outputs) as well.
invoice_amount = 100_000
# invoice_amount = 100_000
fee_reserve = 2_000
total_provided = invoice_amount + fee_reserve
# total_provided = invoice_amount + fee_reserve
actual_fee = 100
expected_returned_promises = 4 # Amounts = [64, 256, 512, 1024]
@@ -179,9 +180,7 @@ async def test_generate_change_promises_legacy_wallet(ledger: Ledger):
for b, _ in blinded_msgs
]
promises = await ledger._generate_change_promises(
total_provided, invoice_amount, actual_fee, outputs
)
promises = await ledger._generate_change_promises(fee_reserve, actual_fee, outputs)
assert len(promises) == expected_returned_promises
assert sum([promise.amount for promise in promises]) == expected_returned_fees
@@ -189,14 +188,14 @@ async def test_generate_change_promises_legacy_wallet(ledger: Ledger):
@pytest.mark.asyncio
async def test_generate_change_promises_returns_empty_if_no_outputs(ledger: Ledger):
invoice_amount = 100_000
# invoice_amount = 100_000
fee_reserve = 1_000
total_provided = invoice_amount + fee_reserve
# total_provided = invoice_amount + fee_reserve
actual_fee_msat = 100_000
outputs = None
promises = await ledger._generate_change_promises(
total_provided, invoice_amount, actual_fee_msat, outputs
fee_reserve, actual_fee_msat, outputs
)
assert len(promises) == 0

View File

@@ -3,14 +3,14 @@ import httpx
import pytest
import pytest_asyncio
from cashu.core.base import (
from cashu.core.base import SpentState
from cashu.core.models import (
GetInfoResponse,
MintMeltMethodSetting,
PostCheckStateRequest,
PostCheckStateResponse,
PostRestoreRequest,
PostRestoreResponse,
SpentState,
)
from cashu.core.settings import settings
from cashu.mint.ledger import Ledger
@@ -89,6 +89,7 @@ async def test_api_keysets(ledger: Ledger):
"id": "009a1f293253e41e",
"unit": "sat",
"active": True,
"input_fee_ppk": 0,
},
]
}

View File

@@ -2,12 +2,12 @@ import httpx
import pytest
import pytest_asyncio
from cashu.core.base import (
from cashu.core.base import Proof
from cashu.core.models import (
CheckSpendableRequest_deprecated,
CheckSpendableResponse_deprecated,
PostRestoreRequest,
PostRestoreResponse,
Proof,
)
from cashu.mint.ledger import Ledger
from cashu.wallet.crud import bump_secret_derivation

View File

@@ -1,7 +1,7 @@
import pytest
import pytest_asyncio
from cashu.core.base import PostMeltQuoteRequest
from cashu.core.models import PostMeltQuoteRequest
from cashu.mint.ledger import Ledger
from cashu.wallet.wallet import Wallet
from cashu.wallet.wallet import Wallet as Wallet1

241
tests/test_mint_fees.py Normal file
View File

@@ -0,0 +1,241 @@
from typing import Optional
import pytest
import pytest_asyncio
from cashu.core.helpers import sum_proofs
from cashu.core.models import PostMeltQuoteRequest
from cashu.core.split import amount_split
from cashu.mint.ledger import Ledger
from cashu.wallet.wallet import Wallet
from cashu.wallet.wallet import Wallet as Wallet1
from tests.conftest import SERVER_ENDPOINT
from tests.helpers import get_real_invoice, is_fake, is_regtest, pay_if_regtest
async def assert_err(f, msg):
"""Compute f() and expect an error message 'msg'."""
try:
await f
except Exception as exc:
if msg not in str(exc.args[0]):
raise Exception(f"Expected error: {msg}, got: {exc.args[0]}")
return
raise Exception(f"Expected error: {msg}, got no error")
@pytest_asyncio.fixture(scope="function")
async def wallet1(ledger: Ledger):
wallet1 = await Wallet1.with_db(
url=SERVER_ENDPOINT,
db="test_data/wallet1",
name="wallet1",
)
await wallet1.load_mint()
yield wallet1
def set_ledger_keyset_fees(
fee_ppk: int, ledger: Ledger, wallet: Optional[Wallet] = None
):
for keyset in ledger.keysets.values():
keyset.input_fee_ppk = fee_ppk
if wallet:
for wallet_keyset in wallet.keysets.values():
wallet_keyset.input_fee_ppk = fee_ppk
@pytest.mark.asyncio
async def test_get_fees_for_proofs(wallet1: Wallet, ledger: Ledger):
invoice = await wallet1.request_mint(64)
pay_if_regtest(invoice.bolt11)
await wallet1.mint(64, split=[1] * 64, id=invoice.id)
# two proofs
set_ledger_keyset_fees(100, ledger)
proofs = [wallet1.proofs[0], wallet1.proofs[1]]
fees = ledger.get_fees_for_proofs(proofs)
assert fees == 1
set_ledger_keyset_fees(1234, ledger)
fees = ledger.get_fees_for_proofs(proofs)
assert fees == 3
set_ledger_keyset_fees(0, ledger)
fees = ledger.get_fees_for_proofs(proofs)
assert fees == 0
set_ledger_keyset_fees(1, ledger)
fees = ledger.get_fees_for_proofs(proofs)
assert fees == 1
# ten proofs
ten_proofs = wallet1.proofs[:10]
set_ledger_keyset_fees(100, ledger)
fees = ledger.get_fees_for_proofs(ten_proofs)
assert fees == 1
set_ledger_keyset_fees(101, ledger)
fees = ledger.get_fees_for_proofs(ten_proofs)
assert fees == 2
# three proofs
three_proofs = wallet1.proofs[:3]
set_ledger_keyset_fees(333, ledger)
fees = ledger.get_fees_for_proofs(three_proofs)
assert fees == 1
set_ledger_keyset_fees(334, ledger)
fees = ledger.get_fees_for_proofs(three_proofs)
assert fees == 2
@pytest.mark.asyncio
@pytest.mark.skipif_with_fees(is_regtest, reason="only works with FakeWallet")
async def test_wallet_fee(wallet1: Wallet, ledger: Ledger):
# THIS TEST IS A FAKE, WE SET THE WALLET FEES MANUALLY IN set_ledger_keyset_fees
# It would be better to test if the wallet can get the fees from the mint itself
# but the ledger instance does not update the responses from the `mint` that is running in the background
# so we just pretend here and test really nothing...
# set fees to 100 ppk
set_ledger_keyset_fees(100, ledger, wallet1)
# check if all wallet keysets have the correct fees
for keyset in wallet1.keysets.values():
assert keyset.input_fee_ppk == 100
@pytest.mark.asyncio
async def test_split_with_fees(wallet1: Wallet, ledger: Ledger):
# set fees to 100 ppk
set_ledger_keyset_fees(100, ledger)
invoice = await wallet1.request_mint(64)
pay_if_regtest(invoice.bolt11)
await wallet1.mint(64, id=invoice.id)
send_proofs, _ = await wallet1.select_to_send(wallet1.proofs, 10)
fees = ledger.get_fees_for_proofs(send_proofs)
assert fees == 1
outputs = await wallet1.construct_outputs(amount_split(9))
promises = await ledger.split(proofs=send_proofs, outputs=outputs)
assert len(promises) == len(outputs)
assert [p.amount for p in promises] == [p.amount for p in outputs]
@pytest.mark.asyncio
async def test_split_with_high_fees(wallet1: Wallet, ledger: Ledger):
# set fees to 100 ppk
set_ledger_keyset_fees(1234, ledger)
invoice = await wallet1.request_mint(64)
pay_if_regtest(invoice.bolt11)
await wallet1.mint(64, id=invoice.id)
send_proofs, _ = await wallet1.select_to_send(wallet1.proofs, 10)
fees = ledger.get_fees_for_proofs(send_proofs)
assert fees == 3
outputs = await wallet1.construct_outputs(amount_split(7))
promises = await ledger.split(proofs=send_proofs, outputs=outputs)
assert len(promises) == len(outputs)
assert [p.amount for p in promises] == [p.amount for p in outputs]
@pytest.mark.asyncio
async def test_split_not_enough_fees(wallet1: Wallet, ledger: Ledger):
# set fees to 100 ppk
set_ledger_keyset_fees(100, ledger)
invoice = await wallet1.request_mint(64)
pay_if_regtest(invoice.bolt11)
await wallet1.mint(64, id=invoice.id)
send_proofs, _ = await wallet1.select_to_send(wallet1.proofs, 10)
fees = ledger.get_fees_for_proofs(send_proofs)
assert fees == 1
# with 10 sat input, we request 10 sat outputs but fees are 1 sat so the swap will fail
outputs = await wallet1.construct_outputs(amount_split(10))
await assert_err(
ledger.split(proofs=send_proofs, outputs=outputs), "are not balanced"
)
@pytest.mark.asyncio
@pytest.mark.skipif(is_regtest, reason="only works with FakeWallet")
async def test_melt_internal(wallet1: Wallet, ledger: Ledger):
# set fees to 100 ppk
set_ledger_keyset_fees(100, ledger, wallet1)
# mint twice so we have enough to pay the second invoice back
invoice = await wallet1.request_mint(128)
await wallet1.mint(128, id=invoice.id)
assert wallet1.balance == 128
# create a mint quote so that we can melt to it internally
invoice_to_pay = await wallet1.request_mint(64)
invoice_payment_request = invoice_to_pay.bolt11
melt_quote = await ledger.melt_quote(
PostMeltQuoteRequest(request=invoice_payment_request, unit="sat")
)
assert not melt_quote.paid
assert melt_quote.amount == 64
assert melt_quote.fee_reserve == 0
melt_quote_pre_payment = await ledger.get_melt_quote(melt_quote.quote)
assert not melt_quote_pre_payment.paid, "melt quote should not be paid"
# let's first try to melt without enough funds
send_proofs, fees = await wallet1.select_to_send(wallet1.proofs, 63)
# this should fail because we need 64 + 1 sat fees
assert sum_proofs(send_proofs) == 64
await assert_err(
ledger.melt(proofs=send_proofs, quote=melt_quote.quote),
"not enough inputs provided for melt",
)
# the wallet respects the fees for coin selection
send_proofs, fees = await wallet1.select_to_send(wallet1.proofs, 64)
# includes 1 sat fees
assert sum_proofs(send_proofs) == 65
await ledger.melt(proofs=send_proofs, quote=melt_quote.quote)
melt_quote_post_payment = await ledger.get_melt_quote(melt_quote.quote)
assert melt_quote_post_payment.paid, "melt quote should be paid"
@pytest.mark.asyncio
@pytest.mark.skipif(is_fake, reason="only works with Regtest")
async def test_melt_external_with_fees(wallet1: Wallet, ledger: Ledger):
# set fees to 100 ppk
set_ledger_keyset_fees(100, ledger, wallet1)
# mint twice so we have enough to pay the second invoice back
invoice = await wallet1.request_mint(128)
pay_if_regtest(invoice.bolt11)
await wallet1.mint(128, id=invoice.id)
assert wallet1.balance == 128
invoice_dict = get_real_invoice(64)
invoice_payment_request = invoice_dict["payment_request"]
mint_quote = await wallet1.melt_quote(invoice_payment_request)
total_amount = mint_quote.amount + mint_quote.fee_reserve
send_proofs, fee = await wallet1.select_to_send(wallet1.proofs, total_amount)
melt_quote = await ledger.melt_quote(
PostMeltQuoteRequest(request=invoice_payment_request, unit="sat")
)
melt_quote_pre_payment = await ledger.get_melt_quote(melt_quote.quote)
assert not melt_quote_pre_payment.paid, "melt quote should not be paid"
assert not melt_quote.paid, "melt quote should not be paid"
await ledger.melt(proofs=send_proofs, quote=melt_quote.quote)
melt_quote_post_payment = await ledger.get_melt_quote(melt_quote.quote)
assert melt_quote_post_payment.paid, "melt quote should be paid"

View File

@@ -2,7 +2,8 @@ import pytest
import respx
from httpx import Response
from cashu.core.base import Amount, MeltQuote, PostMeltQuoteRequest, Unit
from cashu.core.base import Amount, MeltQuote, Unit
from cashu.core.models import PostMeltQuoteRequest
from cashu.core.settings import settings
from cashu.lightning.blink import MINIMUM_FEE_MSAT, BlinkWallet # type: ignore

View File

@@ -1,8 +1,8 @@
import pytest
import pytest_asyncio
from cashu.core.base import PostMeltQuoteRequest, PostMintQuoteRequest
from cashu.core.helpers import sum_proofs
from cashu.core.models import PostMeltQuoteRequest, PostMintQuoteRequest
from cashu.mint.ledger import Ledger
from cashu.wallet.wallet import Wallet
from cashu.wallet.wallet import Wallet as Wallet1
@@ -155,6 +155,18 @@ async def test_split(wallet1: Wallet, ledger: Ledger):
assert [p.amount for p in promises] == [p.amount for p in outputs]
@pytest.mark.asyncio
async def test_split_with_no_outputs(wallet1: Wallet, ledger: Ledger):
invoice = await wallet1.request_mint(64)
pay_if_regtest(invoice.bolt11)
await wallet1.mint(64, id=invoice.id)
_, send_proofs = await wallet1.split_to_send(wallet1.proofs, 10, set_reserved=False)
await assert_err(
ledger.split(proofs=send_proofs, outputs=[]),
"no outputs provided",
)
@pytest.mark.asyncio
async def test_split_with_input_less_than_outputs(wallet1: Wallet, ledger: Ledger):
invoice = await wallet1.request_mint(64)
@@ -165,19 +177,19 @@ async def test_split_with_input_less_than_outputs(wallet1: Wallet, ledger: Ledge
wallet1.proofs, 10, set_reserved=False
)
all_send_proofs = send_proofs + keep_proofs
too_many_proofs = send_proofs + send_proofs
# generate outputs for all proofs, not only the sent ones
# generate more outputs than inputs
secrets, rs, derivation_paths = await wallet1.generate_n_secrets(
len(all_send_proofs)
len(too_many_proofs)
)
outputs, rs = wallet1._construct_outputs(
[p.amount for p in all_send_proofs], secrets, rs
[p.amount for p in too_many_proofs], secrets, rs
)
await assert_err(
ledger.split(proofs=send_proofs, outputs=outputs),
"inputs do not have same amount as outputs.",
"are not balanced",
)
# make sure we can still spend our tokens
@@ -201,7 +213,7 @@ async def test_split_with_input_more_than_outputs(wallet1: Wallet, ledger: Ledge
await assert_err(
ledger.split(proofs=inputs, outputs=outputs),
"inputs do not have same amount as outputs",
"are not balanced",
)
# make sure we can still spend our tokens
@@ -216,6 +228,9 @@ async def test_split_twice_with_same_outputs(wallet1: Wallet, ledger: Ledger):
inputs1 = wallet1.proofs[:1]
inputs2 = wallet1.proofs[1:]
assert inputs1[0].amount == 64
assert inputs2[0].amount == 64
output_amounts = [64]
secrets, rs, derivation_paths = await wallet1.generate_n_secrets(
len(output_amounts)

View File

@@ -42,14 +42,14 @@ async def assert_err(f, msg: Union[str, CashuError]):
def assert_amt(proofs: List[Proof], expected: int):
"""Assert amounts the proofs contain."""
assert [p.amount for p in proofs] == expected
assert sum([p.amount for p in proofs]) == expected
async def reset_wallet_db(wallet: Wallet):
await wallet.db.execute("DELETE FROM proofs")
await wallet.db.execute("DELETE FROM proofs_used")
await wallet.db.execute("DELETE FROM keysets")
await wallet._load_mint()
await wallet.load_mint()
@pytest_asyncio.fixture(scope="function")
@@ -97,7 +97,7 @@ async def test_get_keyset(wallet1: Wallet):
# gets the keys of a specific keyset
assert keyset.id is not None
assert keyset.public_keys is not None
keys2 = await wallet1._get_keys_of_keyset(keyset.id)
keys2 = await wallet1._get_keyset(keyset.id)
assert keys2.public_keys is not None
assert len(keyset.public_keys) == len(keys2.public_keys)
@@ -105,12 +105,12 @@ async def test_get_keyset(wallet1: Wallet):
@pytest.mark.asyncio
async def test_get_keyset_from_db(wallet1: Wallet):
# first load it from the mint
# await wallet1._load_mint_keys()
# await wallet1.activate_keyset()
# NOTE: conftest already called wallet.load_mint() which got the keys from the mint
keyset1 = copy.copy(wallet1.keysets[wallet1.keyset_id])
# then load it from the db
await wallet1._load_mint_keys()
await wallet1.activate_keyset()
keyset2 = copy.copy(wallet1.keysets[wallet1.keyset_id])
assert keyset1.public_keys == keyset2.public_keys
@@ -133,17 +133,17 @@ async def test_get_info(wallet1: Wallet):
@pytest.mark.asyncio
async def test_get_nonexistent_keyset(wallet1: Wallet):
await assert_err(
wallet1._get_keys_of_keyset("nonexistent"),
wallet1._get_keyset("nonexistent"),
KeysetNotFoundError(),
)
@pytest.mark.asyncio
async def test_get_keyset_ids(wallet1: Wallet):
keysets = await wallet1._get_keyset_ids()
async def test_get_keysets(wallet1: Wallet):
keysets = await wallet1._get_keysets()
assert isinstance(keysets, list)
assert len(keysets) > 0
assert wallet1.keyset_id in keysets
assert wallet1.keyset_id in [k.id for k in keysets]
@pytest.mark.asyncio
@@ -156,6 +156,7 @@ async def test_request_mint(wallet1: Wallet):
async def test_mint(wallet1: Wallet):
invoice = await wallet1.request_mint(64)
pay_if_regtest(invoice.bolt11)
expected_proof_amounts = wallet1.split_wallet_state(64)
await wallet1.mint(64, id=invoice.id)
assert wallet1.balance == 64
@@ -168,7 +169,8 @@ async def test_mint(wallet1: Wallet):
proofs_minted = await get_proofs(
db=wallet1.db, mint_id=invoice_db.id, table="proofs"
)
assert len(proofs_minted) == 1
assert len(proofs_minted) == len(expected_proof_amounts)
assert all([p.amount in expected_proof_amounts for p in proofs_minted])
assert all([p.mint_id == invoice.id for p in proofs_minted])
@@ -212,11 +214,15 @@ async def test_split(wallet1: Wallet):
pay_if_regtest(invoice.bolt11)
await wallet1.mint(64, id=invoice.id)
assert wallet1.balance == 64
# the outputs we keep that we expect after the split
expected_proof_amounts = wallet1.split_wallet_state(44)
p1, p2 = await wallet1.split(wallet1.proofs, 20)
assert wallet1.balance == 64
assert sum_proofs(p1) == 44
assert [p.amount for p in p1] == [4, 8, 32]
# what we keep should have the expected amounts
assert [p.amount for p in p1] == expected_proof_amounts
assert sum_proofs(p2) == 20
# what we send should be the optimal split
assert [p.amount for p in p2] == [4, 16]
assert all([p.id == wallet1.keyset_id for p in p1])
assert all([p.id == wallet1.keyset_id for p in p2])
@@ -227,13 +233,19 @@ async def test_split_to_send(wallet1: Wallet):
invoice = await wallet1.request_mint(64)
pay_if_regtest(invoice.bolt11)
await wallet1.mint(64, id=invoice.id)
keep_proofs, spendable_proofs = await wallet1.split_to_send(
assert wallet1.balance == 64
# this will select 32 sats and them (nothing to keep)
keep_proofs, send_proofs = await wallet1.split_to_send(
wallet1.proofs, 32, set_reserved=True
)
get_spendable = await wallet1._select_proofs_to_send(wallet1.proofs, 32)
assert keep_proofs == get_spendable
assert_amt(send_proofs, 32)
assert_amt(keep_proofs, 0)
spendable_proofs = await wallet1._select_proofs_to_send(wallet1.proofs, 32)
assert sum_proofs(spendable_proofs) == 32
assert sum_proofs(send_proofs) == 32
assert wallet1.balance == 64
assert wallet1.available_balance == 32
@@ -271,7 +283,7 @@ async def test_melt(wallet1: Wallet):
invoice_payment_hash = str(invoice.payment_hash)
invoice_payment_request = invoice.bolt11
quote = await wallet1.request_melt(invoice_payment_request)
quote = await wallet1.melt_quote(invoice_payment_request)
total_amount = quote.amount + quote.fee_reserve
if is_regtest:
@@ -421,7 +433,7 @@ async def test_split_invalid_amount(wallet1: Wallet):
await wallet1.mint(64, id=invoice.id)
await assert_err(
wallet1.split(wallet1.proofs, -1),
"amount must be positive.",
"amount can't be negative",
)
@@ -436,13 +448,13 @@ async def test_token_state(wallet1: Wallet):
@pytest.mark.asyncio
async def test_load_mint_keys_specific_keyset(wallet1: Wallet):
await wallet1._load_mint_keys()
async def testactivate_keyset_specific_keyset(wallet1: Wallet):
await wallet1.activate_keyset()
assert list(wallet1.keysets.keys()) == ["009a1f293253e41e"]
await wallet1._load_mint_keys(keyset_id=wallet1.keyset_id)
await wallet1._load_mint_keys(keyset_id="009a1f293253e41e")
await wallet1.activate_keyset(keyset_id=wallet1.keyset_id)
await wallet1.activate_keyset(keyset_id="009a1f293253e41e")
# expect deprecated keyset id to be present
await assert_err(
wallet1._load_mint_keys(keyset_id="nonexistent"),
KeysetNotFoundError(),
wallet1.activate_keyset(keyset_id="nonexistent"),
KeysetNotFoundError("nonexistent"),
)

View File

@@ -65,16 +65,16 @@ async def test_send(wallet: Wallet):
@pytest.mark.asyncio
async def test_send_without_split(wallet: Wallet):
with TestClient(app) as client:
response = client.post("/send?amount=2&nosplit=true")
response = client.post("/send?amount=2&offline=true")
assert response.status_code == 200
assert response.json()["balance"]
@pytest.mark.skipif(is_regtest, reason="regtest")
@pytest.mark.asyncio
async def test_send_without_split_but_wrong_amount(wallet: Wallet):
async def test_send_too_much(wallet: Wallet):
with TestClient(app) as client:
response = client.post("/send?amount=10&nosplit=true")
response = client.post("/send?amount=110000")
assert response.status_code == 400

View File

@@ -175,6 +175,7 @@ def test_invoice_with_split(mint, cli_prefix):
wallet = asyncio.run(init_wallet())
assert wallet.proof_amounts.count(1) >= 10
@pytest.mark.skipif(not is_fake, reason="only on fakewallet")
def test_invoices_with_minting(cli_prefix):
# arrange
@@ -223,6 +224,7 @@ def test_invoices_without_minting(cli_prefix):
assert get_invoice_from_invoices_command(result.output)["ID"] == invoice.id
assert get_invoice_from_invoices_command(result.output)["Paid"] == str(invoice.paid)
@pytest.mark.skipif(not is_fake, reason="only on fakewallet")
def test_invoices_with_onlypaid_option(cli_prefix):
# arrange
@@ -263,6 +265,7 @@ def test_invoices_with_onlypaid_option_without_minting(cli_prefix):
assert result.exit_code == 0
assert "No invoices found." in result.output
@pytest.mark.skipif(not is_fake, reason="only on fakewallet")
def test_invoices_with_onlyunpaid_option(cli_prefix):
# arrange
@@ -322,6 +325,7 @@ def test_invoices_with_both_onlypaid_and_onlyunpaid_options(cli_prefix):
in result.output
)
@pytest.mark.skipif(not is_fake, reason="only on fakewallet")
def test_invoices_with_pending_option(cli_prefix):
# arrange
@@ -422,11 +426,11 @@ def test_send_legacy(mint, cli_prefix):
assert token_str.startswith("eyJwcm9v"), "output is not as expected"
def test_send_without_split(mint, cli_prefix):
def test_send_offline(mint, cli_prefix):
runner = CliRunner()
result = runner.invoke(
cli,
[*cli_prefix, "send", "2", "--nosplit"],
[*cli_prefix, "send", "2", "--offline"],
)
assert result.exception is None
print("SEND")
@@ -434,13 +438,13 @@ def test_send_without_split(mint, cli_prefix):
assert "cashuA" in result.output, "output does not have a token"
def test_send_without_split_but_wrong_amount(mint, cli_prefix):
def test_send_too_much(mint, cli_prefix):
runner = CliRunner()
result = runner.invoke(
cli,
[*cli_prefix, "send", "10", "--nosplit"],
[*cli_prefix, "send", "100000"],
)
assert "No proof with this amount found" in str(result.exception)
assert "balance too low" in str(result.exception)
def test_receive_tokenv3(mint, cli_prefix):

View File

@@ -37,7 +37,7 @@ async def reset_wallet_db(wallet: LightningWallet):
await wallet.db.execute("DELETE FROM proofs")
await wallet.db.execute("DELETE FROM proofs_used")
await wallet.db.execute("DELETE FROM keysets")
await wallet._load_mint()
await wallet.load_mint()
@pytest_asyncio.fixture(scope="function")

View File

@@ -42,7 +42,7 @@ async def reset_wallet_db(wallet: Wallet):
await wallet.db.execute("DELETE FROM proofs")
await wallet.db.execute("DELETE FROM proofs_used")
await wallet.db.execute("DELETE FROM keysets")
await wallet._load_mint()
await wallet.load_mint()
@pytest_asyncio.fixture(scope="function")
@@ -206,7 +206,7 @@ async def test_restore_wallet_after_split_to_send(wallet3: Wallet):
wallet3.proofs = []
assert wallet3.balance == 0
await wallet3.restore_promises_from_to(0, 100)
assert wallet3.balance == 64 * 2
assert wallet3.balance == 96
await wallet3.invalidate(wallet3.proofs, check_spendable=True)
assert wallet3.balance == 64
@@ -233,7 +233,7 @@ async def test_restore_wallet_after_send_and_receive(wallet3: Wallet, wallet2: W
assert wallet3.proofs == []
assert wallet3.balance == 0
await wallet3.restore_promises_from_to(0, 100)
assert wallet3.balance == 64 + 2 * 32
assert wallet3.balance == 96
await wallet3.invalidate(wallet3.proofs, check_spendable=True)
assert wallet3.balance == 32
@@ -276,7 +276,7 @@ async def test_restore_wallet_after_send_and_self_receive(wallet3: Wallet):
assert wallet3.proofs == []
assert wallet3.balance == 0
await wallet3.restore_promises_from_to(0, 100)
assert wallet3.balance == 64 + 2 * 32 + 32
assert wallet3.balance == 128
await wallet3.invalidate(wallet3.proofs, check_spendable=True)
assert wallet3.balance == 64
@@ -311,7 +311,7 @@ async def test_restore_wallet_after_send_twice(
assert wallet3.balance == 0
await wallet3.restore_promises_from_to(0, 10)
box.add(wallet3.proofs)
assert wallet3.balance == 5
assert wallet3.balance == 4
await wallet3.invalidate(wallet3.proofs, check_spendable=True)
assert wallet3.balance == 2
@@ -333,7 +333,7 @@ async def test_restore_wallet_after_send_twice(
assert wallet3.balance == 0
await wallet3.restore_promises_from_to(0, 15)
box.add(wallet3.proofs)
assert wallet3.balance == 7
assert wallet3.balance == 6
await wallet3.invalidate(wallet3.proofs, check_spendable=True)
assert wallet3.balance == 2
@@ -370,7 +370,7 @@ async def test_restore_wallet_after_send_and_self_receive_nonquadratic_value(
assert wallet3.balance == 0
await wallet3.restore_promises_from_to(0, 20)
box.add(wallet3.proofs)
assert wallet3.balance == 138
assert wallet3.balance == 84
await wallet3.invalidate(wallet3.proofs, check_spendable=True)
assert wallet3.balance == 64
@@ -389,6 +389,6 @@ async def test_restore_wallet_after_send_and_self_receive_nonquadratic_value(
assert wallet3.proofs == []
assert wallet3.balance == 0
await wallet3.restore_promises_from_to(0, 50)
assert wallet3.balance == 182
assert wallet3.balance == 108
await wallet3.invalidate(wallet3.proofs, check_spendable=True)
assert wallet3.balance == 64