mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-23 19:54:18 +01:00
Allow arbitrary denominations in wallet minting (#684)
- Update `mint` method to use allowed amounts from the mint - Add `get_allowed_amounts` method to fetch supported denominations - Modify `test_mint_amounts_wrong_order` to expect new error message Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
This commit is contained in:
@@ -111,6 +111,21 @@ class WalletTransactions(SupportsDb, SupportsKeysets):
|
||||
proofs_send = self.coinselect(proofs, amount, include_fees=True)
|
||||
return self.get_fees_for_proofs(proofs_send)
|
||||
|
||||
def get_allowed_amounts(self):
|
||||
"""
|
||||
Infer the allowed amounts from the current keyset's public keys.
|
||||
|
||||
Returns:
|
||||
List[int]: A sorted list of allowed token amounts for the current keyset.
|
||||
|
||||
Raises:
|
||||
Exception: If no active keyset is set.
|
||||
"""
|
||||
|
||||
if not self.keyset_id or self.keyset_id not in self.keysets:
|
||||
raise Exception("No active keyset")
|
||||
return sorted(list(self.keysets[self.keyset_id].public_keys.keys()))
|
||||
|
||||
def split_wallet_state(self, amount: int) -> List[int]:
|
||||
"""This function produces an amount split for outputs based on the current state of the wallet.
|
||||
Its objective is to fill up the wallet so that it reaches `n_target` coins of each amount.
|
||||
@@ -125,8 +140,9 @@ class WalletTransactions(SupportsDb, SupportsKeysets):
|
||||
n_target = settings.wallet_target_amount_count
|
||||
amounts_we_have = [p.amount for p in self.proofs if p.reserved is not True]
|
||||
amounts_we_have.sort()
|
||||
# NOTE: Do not assume 2^n here
|
||||
all_possible_amounts: list[int] = [2**i for i in range(settings.max_order)]
|
||||
|
||||
all_possible_amounts = self.get_allowed_amounts()
|
||||
|
||||
amounts_we_want_ll = [
|
||||
[a] * max(0, n_target - amounts_we_have.count(a))
|
||||
for a in all_possible_amounts
|
||||
|
||||
@@ -519,6 +519,8 @@ class Wallet(
|
||||
await store_bolt11_mint_quote(db=self.db, quote=quote)
|
||||
return quote
|
||||
|
||||
|
||||
|
||||
async def mint(
|
||||
self,
|
||||
amount: int,
|
||||
@@ -529,7 +531,7 @@ class Wallet(
|
||||
|
||||
Args:
|
||||
amount (int): Total amount of tokens to be minted
|
||||
id (str): Id for looking up the paid Lightning invoice.
|
||||
quote_id (str): Id for looking up the paid Lightning invoice.
|
||||
split (Optional[List[str]], optional): List of desired amount splits to be minted. Total must sum to `amount`.
|
||||
|
||||
Raises:
|
||||
@@ -543,11 +545,11 @@ class Wallet(
|
||||
if split:
|
||||
logger.trace(f"Mint with split: {split}")
|
||||
assert sum(split) == amount, "split must sum to amount"
|
||||
allowed_amounts = [2**i for i in range(settings.max_order)]
|
||||
allowed_amounts = self.get_allowed_amounts() # Get allowed amounts from the mint
|
||||
for a in split:
|
||||
if a not in allowed_amounts:
|
||||
raise Exception(
|
||||
f"Can only mint amounts with 2^n up to {2**settings.max_order}."
|
||||
f"Can only mint amounts supported by the mint: {allowed_amounts}"
|
||||
)
|
||||
|
||||
# split based on our wallet state
|
||||
|
||||
@@ -221,9 +221,10 @@ async def test_mint_amounts_wrong_order(wallet1: Wallet):
|
||||
"""Mint amount that is not part in 2^n"""
|
||||
amts = [1, 2, 3]
|
||||
mint_quote = await wallet1.request_mint(sum(amts))
|
||||
allowed_amounts = wallet1.get_allowed_amounts()
|
||||
await assert_err(
|
||||
wallet1.mint(amount=sum(amts), split=[1, 2, 3], quote_id=mint_quote.quote),
|
||||
f"Can only mint amounts with 2^n up to {2**settings.max_order}.",
|
||||
f"Can only mint amounts supported by the mint: {allowed_amounts}",
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user