Skip to content

Commit

Permalink
blink: round up fees to next satoshi (#445)
Browse files Browse the repository at this point in the history
  • Loading branch information
callebtc authored Feb 19, 2024
1 parent 1e26f23 commit 2189728
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
14 changes: 11 additions & 3 deletions cashu/lightning/blink.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,18 @@ async def get_payment_quote(self, bolt11: str) -> PaymentQuoteResponse:

amount_msat = int(invoice_obj.amount_msat)

# we take the highest: fee_msat_response, or BLINK_MAX_FEE_PERCENT, or 2000 msat
fees_msat = max(
# we take the highest: fee_msat_response, or BLINK_MAX_FEE_PERCENT, or MINIMUM_FEE_MSAT msat
# Note: fees with BLINK_MAX_FEE_PERCENT are rounded to the nearest 1000 msat
fees_amount_msat: int = (
math.ceil(amount_msat / 100 * BLINK_MAX_FEE_PERCENT / 1000) * 1000
)

fees_msat: int = max(
fees_response_msat,
max(math.ceil(amount_msat / 100 * BLINK_MAX_FEE_PERCENT), MINIMUM_FEE_MSAT),
max(
fees_amount_msat,
MINIMUM_FEE_MSAT,
),
)

fees = Amount(unit=Unit.msat, amount=fees_msat)
Expand Down
39 changes: 36 additions & 3 deletions tests/test_mint_lightning_blink.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,31 @@

from cashu.core.base import Amount, MeltQuote, Unit
from cashu.core.settings import settings
from cashu.lightning.blink import BlinkWallet
from cashu.lightning.blink import MINIMUM_FEE_MSAT, BlinkWallet

settings.mint_blink_key = "123"
blink = BlinkWallet()
payment_request = (
"lnbc10u1pjap7phpp50s9lzr3477j0tvacpfy2ucrs4q0q6cvn232ex7nt2zqxxxj8gxrsdpv2phhwetjv4jzqcneypqyc6t8dp6xu6twva2xjuzzda6qcqzzsxqrrsss"
"p575z0n39w2j7zgnpqtdlrgz9rycner4eptjm3lz363dzylnrm3h4s9qyyssqfz8jglcshnlcf0zkw4qu8fyr564lg59x5al724kms3h6gpuhx9xrfv27tgx3l3u3cyf6"
"3r52u0xmac6max8mdupghfzh84t4hfsvrfsqwnuszf"
) # 1000 sat

payment_request_10k = (
"lnbc100u1pjaxuyzpp5wn37d3mx38haqs7nd5he4j7pq4r806e6s83jdksxrd77pnanm3zqdpv2phhwetjv4jzqcneypqyc6t8dp6xu6twva2xjuzzda6qcqzzsxqrrss"
"sp5ayy0uuhwgy8hwphvy7ptzpg2dfn8vt3vlgsk53rsvj76jvafhujs9qyyssqc8aj03s5au3tgu6pj0rm0ws4a838s8ffe3y3qkj77esh7qmgsz7qlvdlzgj6dvx7tx7"
"zn6k352z85rvdqvlszrevvzakp96a4pvyn2cpgaaks6"
)

payment_request_4973 = (
"lnbc49730n1pjaxuxnpp5zw0ry2w2heyuv7wk4r6z38vvgnaudfst0hl2p5xnv0mjkxtavg2qdpv2phhwetjv4jzqcneypqyc6t8dp6xu6twva2xjuzzda6qcqzzsxqrr"
"sssp5x8tv2ka0m95hgek25kauw540m0dx727stqqr07l8h37v5283sn5q9qyyssqeevcs6vxcdnerk5w5mwfmntsf8nze7nxrf97dywmga7v0742vhmxtjrulgu3kah4f"
"2r6025j974jpjg4mkqhv2gdls5k7e5cvwdf4wcp3ytsvx"
)
payment_request_1 = (
"lnbc10n1pjaxujrpp5sqehn6h5p8xpa0c0lvj5vy3a537gxfk5e7h2ate2alfw3y5cm6xqdpv2phhwetjv4jzqcneypqyc6t8dp6xu6twva2xjuzzda6qcqzzsxqrrsss"
"p5fkxsvyl0r32mvnhv9cws4rp986v0wjl2lp93zzl8jejnuwzvpynq9qyyssqqmsnatsz87qrgls98c97dfa6l2z3rzg2x6kxmrvpz886rwjylmd56y3qxzfulrq03kkh"
"hwk6r32wes6pjt2zykhnsjn30c6uhuk0wugp3x74al"
)


Expand Down Expand Up @@ -132,18 +149,34 @@ async def test_blink_get_payment_status():
@respx.mock
@pytest.mark.asyncio
async def test_blink_get_payment_quote():
# response says 1 sat fees but invoice * 0.5% is 5 sat so we expect 5 sat
# response says 1 sat fees but invoice (1000 sat) * 0.5% is 5 sat so we expect 5 sat
mock_response = {"data": {"lnInvoiceFeeProbe": {"amount": 1}}}
respx.post(blink.endpoint).mock(return_value=Response(200, json=mock_response))
quote = await blink.get_payment_quote(payment_request)
assert quote.checking_id == payment_request
assert quote.amount == Amount(Unit.msat, 1000000) # msat
assert quote.fee == Amount(Unit.msat, 5000) # msat

# response says 10 sat fees but invoice * 0.5% is 5 sat so we expect 10 sat
# response says 10 sat fees but invoice (1000 sat) * 0.5% is 5 sat so we expect 10 sat
mock_response = {"data": {"lnInvoiceFeeProbe": {"amount": 10}}}
respx.post(blink.endpoint).mock(return_value=Response(200, json=mock_response))
quote = await blink.get_payment_quote(payment_request)
assert quote.checking_id == payment_request
assert quote.amount == Amount(Unit.msat, 1000000) # msat
assert quote.fee == Amount(Unit.msat, 10000) # msat

# response says 10 sat fees but invoice (4973 sat) * 0.5% is 24.865 sat so we expect 25 sat
mock_response = {"data": {"lnInvoiceFeeProbe": {"amount": 10}}}
respx.post(blink.endpoint).mock(return_value=Response(200, json=mock_response))
quote = await blink.get_payment_quote(payment_request_4973)
assert quote.checking_id == payment_request_4973
assert quote.amount == Amount(Unit.msat, 4973000) # msat
assert quote.fee == Amount(Unit.msat, 25000) # msat

# response says 0 sat fees but invoice (1 sat) * 0.5% is 0.005 sat so we expect MINIMUM_FEE_MSAT/1000 sat
mock_response = {"data": {"lnInvoiceFeeProbe": {"amount": 0}}}
respx.post(blink.endpoint).mock(return_value=Response(200, json=mock_response))
quote = await blink.get_payment_quote(payment_request_1)
assert quote.checking_id == payment_request_1
assert quote.amount == Amount(Unit.msat, 1000) # msat
assert quote.fee == Amount(Unit.msat, MINIMUM_FEE_MSAT) # msat

0 comments on commit 2189728

Please sign in to comment.