Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

coinselect #31

Merged
merged 5 commits into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions cashu/wallet/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,18 +548,29 @@ async def serialize_proofs(
token = await self._make_token(proofs, include_mints)
return await self._serialize_token_base64(token)

async def _get_spendable_proofs(self, proofs: List[Proof]):
async def _select_proofs_to_send(self, proofs: List[Proof], amount_to_send: int):
"""
Selects proofs that can be used with the current mint.
Chooses:
1) Proofs that are not marked as reserved
2) Proofs that have a keyset id that is in self.keysets (active keysets of mint) - !!! optional for backwards compatibility with legacy clients
"""
# select proofs that are in the active keysets of the mint
proofs = [
p for p in proofs if p.id in self.keysets or not p.id
] # "or not p.id" is for backwards compatibility with proofs without a keyset id
# select proofs that are not reserved
proofs = [p for p in proofs if not p.reserved]
return proofs
# check that enough spendable proofs exist
if sum_proofs(proofs) < amount_to_send:
raise Exception("balance too low.")

# coinselect based on amount to send
sorted_proofs = sorted(proofs, key=lambda p: p.amount)
send_proofs: List[Proof] = []
while sum_proofs(send_proofs) < amount_to_send:
send_proofs.append(sorted_proofs[len(send_proofs)])
return send_proofs

async def get_pay_amount_with_fees(self, invoice: str):
"""
Expand Down Expand Up @@ -590,9 +601,8 @@ async def split_to_send(
"""Like self.split but only considers non-reserved tokens."""
if scnd_secret:
logger.debug(f"Spending conditions: {scnd_secret}")
spendable_proofs = await self._get_spendable_proofs(proofs)
if sum_proofs(spendable_proofs) < amount:
raise Exception("balance too low.")
spendable_proofs = await self._select_proofs_to_send(proofs, amount)

keep_proofs, send_proofs = await self.split(
[p for p in spendable_proofs if not p.reserved], amount, scnd_secret
)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ async def test_split_to_send(wallet1: Wallet):
keep_proofs, spendable_proofs = await wallet1.split_to_send(
wallet1.proofs, 32, set_reserved=True
)
get_spendable = await wallet1._get_spendable_proofs(wallet1.proofs)
get_spendable = await wallet1._select_proofs_to_send(wallet1.proofs, 32)
assert keep_proofs == get_spendable

assert sum_proofs(spendable_proofs) == 32
Expand Down
Loading