mirror of
https://github.com/aljazceru/nutshell.git
synced 2026-02-03 15:54:20 +01:00
[Wallet] send without split (#249)
* send without split * change test amount for nosplit send
This commit is contained in:
@@ -166,13 +166,16 @@ async def send_command(
|
||||
default=None,
|
||||
description="Mint URL to send from (None for default mint)",
|
||||
),
|
||||
nosplit: bool = Query(
|
||||
default=False, description="Do not split tokens before sending."
|
||||
),
|
||||
):
|
||||
global wallet
|
||||
wallet = await load_mint(wallet, mint)
|
||||
|
||||
await wallet.load_proofs()
|
||||
if not nostr:
|
||||
balance, token = await send(wallet, amount, lock, legacy=False)
|
||||
balance, token = await send(
|
||||
wallet, amount, lock, legacy=False, split=not nosplit
|
||||
)
|
||||
return SendResponse(balance=balance, token=token)
|
||||
else:
|
||||
token, pubkey = await send_nostr(wallet, amount, nostr)
|
||||
|
||||
@@ -275,6 +275,14 @@ async def balance(ctx: Context, verbose):
|
||||
@click.option(
|
||||
"--yes", "-y", default=False, is_flag=True, help="Skip confirmation.", type=bool
|
||||
)
|
||||
@click.option(
|
||||
"--nosplit",
|
||||
"-s",
|
||||
default=False,
|
||||
is_flag=True,
|
||||
help="Do not split tokens before sending.",
|
||||
type=bool,
|
||||
)
|
||||
@click.pass_context
|
||||
@coro
|
||||
async def send_command(
|
||||
@@ -286,10 +294,11 @@ async def send_command(
|
||||
legacy: bool,
|
||||
verbose: bool,
|
||||
yes: bool,
|
||||
nosplit: bool,
|
||||
):
|
||||
wallet: Wallet = ctx.obj["WALLET"]
|
||||
if not nostr and not nopt:
|
||||
await send(wallet, amount, lock, legacy)
|
||||
await send(wallet, amount, lock, legacy, split=not nosplit)
|
||||
else:
|
||||
await send_nostr(wallet, amount, nostr or nopt, verbose, yes)
|
||||
|
||||
|
||||
@@ -114,8 +114,6 @@ async def receive(
|
||||
tokenObj: TokenV3,
|
||||
lock: str,
|
||||
):
|
||||
# await wallet.load_mint()
|
||||
|
||||
# check for P2SH locks
|
||||
if lock:
|
||||
# load the script and signature of this address from the database
|
||||
@@ -166,10 +164,7 @@ async def receive(
|
||||
|
||||
|
||||
async def send(
|
||||
wallet: Wallet,
|
||||
amount: int,
|
||||
lock: str,
|
||||
legacy: bool,
|
||||
wallet: Wallet, amount: int, lock: str, legacy: bool, split: bool = True
|
||||
):
|
||||
"""
|
||||
Prints token to send to stdout.
|
||||
@@ -182,11 +177,24 @@ async def send(
|
||||
if lock and len(lock.split("P2SH:")) == 2:
|
||||
p2sh = True
|
||||
|
||||
await wallet.load_mint()
|
||||
await wallet.load_proofs()
|
||||
_, send_proofs = await wallet.split_to_send(
|
||||
wallet.proofs, amount, lock, set_reserved=True
|
||||
)
|
||||
if split:
|
||||
await wallet.load_mint()
|
||||
_, send_proofs = await wallet.split_to_send(
|
||||
wallet.proofs, amount, lock, set_reserved=True
|
||||
)
|
||||
else:
|
||||
# get a proof with specific amount
|
||||
send_proofs = []
|
||||
for p in wallet.proofs:
|
||||
if not p.reserved and p.amount == amount:
|
||||
send_proofs = [p]
|
||||
break
|
||||
assert send_proofs, Exception(
|
||||
f"No proof with this amount found. Available amounts: {set([p.amount for p in wallet.proofs])}"
|
||||
)
|
||||
await wallet.set_reserved(send_proofs, reserved=True)
|
||||
|
||||
token = await wallet.serialize_proofs(
|
||||
send_proofs,
|
||||
include_mints=True,
|
||||
|
||||
@@ -5,7 +5,7 @@ import secrets as scrts
|
||||
import time
|
||||
import uuid
|
||||
from itertools import groupby
|
||||
from typing import Dict, List, Optional
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
import requests
|
||||
from loguru import logger
|
||||
@@ -355,7 +355,7 @@ class LedgerAPI:
|
||||
|
||||
If scnd_secret is provided, the wallet will create blinded secrets with those to attach a
|
||||
predefined spending condition to the tokens they want to send."""
|
||||
|
||||
logger.debug("Calling split. POST /split")
|
||||
total = sum_proofs(proofs)
|
||||
frst_amt, scnd_amt = total - amount, amount
|
||||
frst_outputs = amount_split(frst_amt)
|
||||
@@ -853,14 +853,6 @@ class Wallet(LedgerAPI):
|
||||
amount = math.ceil((decoded_invoice.amount_msat + fees * 1000) / 1000) # 1% fee
|
||||
return amount, fees
|
||||
|
||||
async def split_to_pay(self, invoice: str):
|
||||
"""
|
||||
Splits proofs such that a Lightning invoice can be paid.
|
||||
"""
|
||||
amount, _ = await self.get_pay_amount_with_fees(invoice)
|
||||
_, send_proofs = await self.split_to_send(self.proofs, amount)
|
||||
return send_proofs
|
||||
|
||||
async def split_to_send(
|
||||
self,
|
||||
proofs: List[Proof],
|
||||
|
||||
@@ -116,6 +116,29 @@ def test_send(mint, cli_prefix):
|
||||
assert "cashuA" in result.output, "output does not have a token"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
def test_send_without_split(mint, cli_prefix):
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
cli,
|
||||
[*cli_prefix, "send", "2", "--nosplit"],
|
||||
)
|
||||
assert result.exception is None
|
||||
print("SEND")
|
||||
print(result.output)
|
||||
assert "cashuA" in result.output, "output does not have a token"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
def test_send_without_split_but_wrong_amount(mint, cli_prefix):
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
cli,
|
||||
[*cli_prefix, "send", "10", "--nosplit"],
|
||||
)
|
||||
assert "No proof with this amount found" in str(result.exception)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
def test_receive_tokenv3(mint, cli_prefix):
|
||||
runner = CliRunner()
|
||||
|
||||
@@ -57,6 +57,19 @@ def test_send(mint):
|
||||
assert response.json()["balance"]
|
||||
|
||||
|
||||
def test_send_without_split(mint):
|
||||
with TestClient(app) as client:
|
||||
response = client.post("/send?amount=1&nosplit=true")
|
||||
assert response.status_code == 200
|
||||
assert response.json()["balance"]
|
||||
|
||||
|
||||
def test_send_without_split_but_wrong_amount(mint):
|
||||
with TestClient(app) as client:
|
||||
response = client.post("/send?amount=10&nosplit=true")
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
def test_pending():
|
||||
with TestClient(app) as client:
|
||||
response = client.get("/pending")
|
||||
|
||||
Reference in New Issue
Block a user