From a53fa7f78e9d2ad26ca85c28da300ae98fde4622 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Sun, 14 Dec 2025 09:22:11 +0000 Subject: [PATCH 01/83] initial --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4576ded..4eff810 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Example Extension - [LNbits](https://github.com/lnbits/lnbits) extension +# Silent Payments Extension - [LNbits](https://github.com/lnbits/lnbits) extension For more about LNBits extension check [this tutorial](https://github.com/lnbits/lnbits/wiki/LNbits-Extensions) From 56f2cb236c81141b6f6af4c71730fa042e5c920d Mon Sep 17 00:00:00 2001 From: Ponthief Date: Sat, 14 Mar 2026 13:12:09 +0000 Subject: [PATCH 02/83] init working --- __init__.py | 48 +- bip32.py | 265 +++ config.json | 32 +- crud.py | 143 +- helpers/curve.py | 187 ++ helpers/wallet.py | 61 + manifest.json | 4 +- migrations.py | 49 +- models.py | 88 +- pyproject.toml | 17 +- static/1.png | Bin 198146 -> 0 bytes static/2.png | Bin 261128 -> 0 bytes static/3.png | Bin 182701 -> 0 bytes static/bitcoin-extension.png | Bin 5343 -> 0 bytes static/bitcoin-wallet.png | Bin 0 -> 12988 bytes static/components/address-list.js | 128 + static/components/fee-rate.js | 61 + static/components/history.js | 96 + static/components/my-checkbox.js | 14 + static/components/payment.js | 419 ++++ static/components/seed-input.js | 100 + static/components/send-to.js | 69 + static/components/utxo-list.js | 146 ++ static/components/wallet-config.js | 66 + static/components/wallet-list.js | 254 ++ static/conversion-example.png | Bin 78613 -> 0 bytes static/conversion-example2.png | Bin 40977 -> 0 bytes static/fastapi-example.png | Bin 84868 -> 0 bytes static/fastapi-example2.png | Bin 59314 -> 0 bytes static/fastapi-framework.png | Bin 1248 -> 0 bytes static/fastapilogo.png | Bin 14237 -> 0 bytes static/js/bip39-word-list.js | 2050 +++++++++++++++++ static/js/crypto/aes.js | 1413 ++++++++++++ static/js/crypto/noble-secp256k1.js | 1178 ++++++++++ static/js/index.js | 482 +++- static/js/map.js | 81 + static/js/tables.js | 61 + static/js/utils.js | 210 ++ static/qrcode-example.png | Bin 10045 -> 0 bytes static/qrcode-example1.png | Bin 34299 -> 0 bytes static/quasar-example.png | Bin 71449 -> 0 bytes static/quasar-framework.png | Bin 2084 -> 0 bytes static/quasarlogo.png | Bin 12555 -> 0 bytes static/script-example.png | Bin 95823 -> 0 bytes static/vif-example.png | Bin 22515 -> 0 bytes static/vuejs-framework.png | Bin 1099 -> 0 bytes static/vuejslogo.png | Bin 9856 -> 0 bytes static/websocket-example.png | Bin 50070 -> 0 bytes tasks.py | 25 - templates/example/index.html | 442 ---- templates/silnt/_api_docs.html | 266 +++ templates/silnt/components/address-list.html | 215 ++ templates/silnt/components/fee-rate.html | 62 + templates/silnt/components/history.html | 144 ++ templates/silnt/components/my-checkbox.html | 5 + templates/silnt/components/payment.html | 310 +++ templates/silnt/components/seed-input.html | 80 + templates/silnt/components/send-to.html | 77 + templates/silnt/components/utxo-list.html | 142 ++ templates/silnt/components/wallet-config.html | 49 + templates/silnt/components/wallet-list.html | 214 ++ templates/silnt/index.html | 326 +++ uv.lock | 235 +- views.py | 21 +- views_api.py | 408 +++- 65 files changed, 10047 insertions(+), 696 deletions(-) create mode 100644 bip32.py create mode 100644 helpers/curve.py create mode 100644 helpers/wallet.py delete mode 100644 static/1.png delete mode 100644 static/2.png delete mode 100644 static/3.png delete mode 100644 static/bitcoin-extension.png create mode 100644 static/bitcoin-wallet.png create mode 100644 static/components/address-list.js create mode 100644 static/components/fee-rate.js create mode 100644 static/components/history.js create mode 100644 static/components/my-checkbox.js create mode 100644 static/components/payment.js create mode 100644 static/components/seed-input.js create mode 100644 static/components/send-to.js create mode 100644 static/components/utxo-list.js create mode 100644 static/components/wallet-config.js create mode 100644 static/components/wallet-list.js delete mode 100644 static/conversion-example.png delete mode 100644 static/conversion-example2.png delete mode 100644 static/fastapi-example.png delete mode 100644 static/fastapi-example2.png delete mode 100644 static/fastapi-framework.png delete mode 100644 static/fastapilogo.png create mode 100644 static/js/bip39-word-list.js create mode 100644 static/js/crypto/aes.js create mode 100644 static/js/crypto/noble-secp256k1.js create mode 100644 static/js/map.js create mode 100644 static/js/tables.js create mode 100644 static/js/utils.js delete mode 100644 static/qrcode-example.png delete mode 100644 static/qrcode-example1.png delete mode 100644 static/quasar-example.png delete mode 100644 static/quasar-framework.png delete mode 100644 static/quasarlogo.png delete mode 100644 static/script-example.png delete mode 100644 static/vif-example.png delete mode 100644 static/vuejs-framework.png delete mode 100644 static/vuejslogo.png delete mode 100644 static/websocket-example.png delete mode 100644 tasks.py delete mode 100644 templates/example/index.html create mode 100644 templates/silnt/_api_docs.html create mode 100644 templates/silnt/components/address-list.html create mode 100644 templates/silnt/components/fee-rate.html create mode 100644 templates/silnt/components/history.html create mode 100644 templates/silnt/components/my-checkbox.html create mode 100644 templates/silnt/components/payment.html create mode 100644 templates/silnt/components/seed-input.html create mode 100644 templates/silnt/components/send-to.html create mode 100644 templates/silnt/components/utxo-list.html create mode 100644 templates/silnt/components/wallet-config.html create mode 100644 templates/silnt/components/wallet-list.html create mode 100644 templates/silnt/index.html diff --git a/__init__.py b/__init__.py index 353d3b4..5d1e3be 100644 --- a/__init__.py +++ b/__init__.py @@ -1,46 +1,20 @@ -import asyncio - from fastapi import APIRouter -from loguru import logger +from fastapi.staticfiles import StaticFiles from .crud import db -from .tasks import wait_for_paid_invoices -from .views import example_ext_generic -from .views_api import example_ext_api - -example_ext: APIRouter = APIRouter(prefix="/example", tags=["example"]) -example_ext.include_router(example_ext_generic) -example_ext.include_router(example_ext_api) +from .views import silnt_generic_router +from .views_api import silnt_api_router -example_static_files = [ +silnt_static_files = [ { - "path": "/example/static", - "name": "example_static", + "path": "/silnt/static", + "app": StaticFiles(packages=[("lnbits", "extensions/silnt/static")]), + "name": "silnt_static", } ] -scheduled_tasks: list[asyncio.Task] = [] - - -def example_stop(): - for task in scheduled_tasks: - try: - task.cancel() - except Exception as ex: - logger.warning(ex) - +silnt_ext: APIRouter = APIRouter(prefix="/silnt", tags=["silnt"]) +silnt_ext.include_router(silnt_generic_router) +silnt_ext.include_router(silnt_api_router) -def example_start(): - from lnbits.tasks import create_permanent_unique_task - - task = create_permanent_unique_task("ext_testing", wait_for_paid_invoices) - scheduled_tasks.append(task) - - -__all__ = [ - "db", - "example_ext", - "example_start", - "example_static_files", - "example_stop", -] +__all__ = ["silnt_ext", "silnt_static_files", "db"] diff --git a/bip32.py b/bip32.py new file mode 100644 index 0000000..6a08b8d --- /dev/null +++ b/bip32.py @@ -0,0 +1,265 @@ +from embit import script +from embit import bip32 +from embit import bip39, base58 +from embit.networks import NETWORKS +import random +import hmac +import os +from typing import Tuple, List +import hashlib +from typing import Tuple +from binascii import unhexlify +from ecdsa import SigningKey, SECP256k1 +# from mnemonic import Mnemonic + +# Elliptic curve parameters +p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F +n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 +G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, + 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8) + +# Points are tuples of X and Y coordinates +# the point at infinity is represented by the None keyword +Point = Tuple[int, int] + +from enum import Enum +from typing import Optional, Tuple + +class Encoding(Enum): + """Enumeration type to list the various supported encodings.""" + BECH32 = 1 + BECH32M = 2 + +CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" +BECH32M_CONST = 0x2bc830a3 + +# Point addition +def point_add(P1: Optional[Point], P2: Optional[Point]) -> Optional[Point]: + if P1 is None: + return P2 + if P2 is None: + return P1 + if (x(P1) == x(P2)) and (y(P1) != y(P2)): + return None + if P1 == P2: + lam = (3 * x(P1) * x(P1) * pow(2 * y(P1), p - 2, p)) % p + else: + lam = ((y(P2) - y(P1)) * pow(x(P2) - x(P1), p - 2, p)) % p + x3 = (lam * lam - x(P1) - x(P2)) % p + return x3, (lam * (x(P1) - x3) - y(P1)) % p + + +# Point multiplication +def point_mul(P: Optional[Point], d: int) -> Optional[Point]: + R = None + for i in range(256): + if (d >> i) & 1: + R = point_add(R, P) + P = point_add(P, P) + return R + +# Check if a point has even y coordinate +def has_even_y(P: Point) -> bool: + return y(P) % 2 == 0 + +# Get bytes from an int +def bytes_from_int(a: int) -> bytes: + return a.to_bytes(32, byteorder="big") + +# Get bytes from a point +def bytes_from_point(P: Point) -> bytes: + return bytes_from_int(x(P)) + +# Get bytes from a hex +def bytes_from_hex(a: str) -> bytes: + return unhexlify(a) + +def hmac_sha512(key: bytes, data: bytes) -> bytes: + return hmac.new(key, data, hashlib.sha512).digest() + + +def derive_hardened_key(master_key: bytes, index: int) -> bytes: + index_bytes = index.to_bytes(4, byteorder='big') + return hmac_sha512(master_key, b'\x00' + master_key + index_bytes) + +def generate_master_key_from_seed(seed_bytes): + # Convert the seed from hex string to bytes + # seed_bytes = bytes.fromhex(seed_hex) + # Use HMAC-SHA512 with "Bitcoin seed" as the key + master_node = hmac.new( + key=b"Bitcoin seed", + msg=seed_bytes, + digestmod=hashlib.sha512 + ).digest() + # Split the 512-bit output into master private key (first 32 bytes) and chain code (last 32 bytes) + master_private_key = master_node[:32] + chain_code = master_node[32:] + return master_private_key, chain_code + +def generate_hardened_keys(master_key) -> dict: + # master_key = os.urandom(32) # 32 bytes + # scan_private_key = derive_hardened_key(master_key, 1) # m/1' + # spend_private_key = derive_hardened_key(master_key, 0) # m/0' + root = bip32.HDKey.from_seed(master_key, version=NETWORKS["main"]["xprv"]) + scan_private_key = root.derive("m/352h/0h/0h/1h/0").key.secret + spend_private_key = root.derive("m/352h/0h/0h/0h/0").key.secret + from binascii import hexlify + scank = root.derive("m/352h/0h/0h/1h/0").key.secret + print(hexlify(scank).decode()) + spendk = root.derive("m/352h/0h/0h/0h/0") + print(spendk.get_public_key()) + # Store the keys in a dictionary + key_material = { + 'scan_priv_key': scan_private_key, + 'spend_priv_key': spend_private_key + } + return key_material + +# Get x coordinate from a point +def x(P: Point) -> int: + return P[0] + + +# Get y coordinate from a point +def y(P: Point) -> int: + return P[1] + +# ser256(p): serializes the integer p as a 32-byte sequence, most significant byte first. +def ser256(p: int) -> bytes: + return p.to_bytes(32, 'big') + +# serP(P): serializes the coordinate pair P = (x,y) as a byte sequence using SEC1's compressed form: +# (0x02 or 0x03) || ser256(x), where the header byte depends on the parity of the omitted Y coordinate. +def serP(P: Point) -> bytes: + x_bytes = ser256(int_from_bytes(bytes_from_point(P))) + prefix = b'\x02' if has_even_y(P) else b'\x03' # Determine the parity of y to choose the prefix + return prefix + x_bytes + +# Get an int from bytes +def int_from_bytes(b: bytes) -> int: + return int.from_bytes(b, byteorder="big") + +def get_seed() -> bytes: + """ + Re‑creates the BIP‑39 seed from the hard‑coded mnemonic. + Returns the 64‑byte seed (as `bytes`) that the Rust code produces. + """ + seed = bip39.mnemonic_to_seed(mnemonic) + return seed + +def bech32_polymod(values: list[int]) -> int: + """Internal function that computes the Bech32 checksum.""" + generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3] + chk = 1 + for value in values: + top = chk >> 25 + chk = (chk & 0x1ffffff) << 5 ^ value + for i in range(5): + chk ^= generator[i] if ((top >> i) & 1) else 0 + return chk + +def bech32_hrp_expand(hrp: str) -> list[int]: + """Expand the HRP into values for checksum computation.""" + return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 31 for x in hrp] + +def bech32_verify_checksum(hrp: str, data: list[int]) -> Optional[Encoding]: + """Verify a checksum given HRP and converted data characters.""" + const = bech32_polymod(bech32_hrp_expand(hrp) + data) + if const == 1: + return Encoding.BECH32 + if const == BECH32M_CONST: + return Encoding.BECH32M + return None + +def decode(hrp: str, addr: str) -> Tuple[Optional[int], Optional[list[int]]]: + """Decode a segwit address.""" + hrpgot, data, _ = bech32_decode(addr) + if hrpgot != hrp: + return (None, None) + decoded = convertbits(data[1:], 5, 8, False) if data else None + if decoded is None or len(decoded) < 2 or len(decoded) > 71: + return (None, None) + if data[0] > 16: + return (None, None) + if data[0] == 0 and len(decoded) != 66: + return (None, None) + return (data[0], decoded) + +def bech32_create_checksum(hrp: str, data: list[int], spec: Encoding) -> list[int]: + """Compute the checksum values given HRP and data.""" + values = bech32_hrp_expand(hrp) + data + const = BECH32M_CONST if spec == Encoding.BECH32M else 1 + polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ const + return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)] + +def bech32_encode(hrp: str, data: list[int], spec: Encoding) -> str: + """Compute a Bech32 string given HRP and data values.""" + combined = data + bech32_create_checksum(hrp, data, spec) + return hrp + '1' + ''.join([CHARSET[d] for d in combined]) + +def convertbits(data: bytes, frombits: int, tobits: int, pad: bool = True) -> Optional[list[int]]: + """General power-of-2 base conversion.""" + acc = 0 + bits = 0 + ret = [] + maxv = (1 << tobits) - 1 + max_acc = (1 << (frombits + tobits - 1)) - 1 + for value in data: + if value < 0 or (value >> frombits): + return None + acc = ((acc << frombits) | value) & max_acc + bits += frombits + while bits >= tobits: + bits -= tobits + ret.append((acc >> bits) & maxv) + if pad: + if bits: + ret.append((acc << (tobits - bits)) & maxv) + elif bits >= frombits or ((acc << (tobits - bits)) & maxv): + return None + return ret +# Generate public key (as a point) from an int +def pubkey_point_gen_from_int(seckey: int) -> Point: + P = point_mul(G, seckey) + assert P is not None + return P + +def bech32_decode(bech: str) -> Tuple[Optional[str], Optional[list[int]], Optional[Encoding]]: + """Validate a Bech32m string, and determine HRP and data.""" + if ((any(ord(x) < 33 or ord(x) > 126 for x in bech)) or + (bech.lower() != bech and bech.upper() != bech)): + return (None, None, None) + bech = bech.lower() + pos = bech.rfind('1') + if pos < 1 or pos + 7 > len(bech) or len(bech) > 117: + return (None, None, None) + if not all(x in CHARSET for x in bech[pos+1:]): + return (None, None, None) + hrp = bech[:pos] + data = [CHARSET.find(x) for x in bech[pos+1:]] + spec = bech32_verify_checksum(hrp, data) + if spec is None: + return (None, None, None) + return (hrp, data[:-6], spec) + + + +def encode_silent_payment_address(B_scan: Point, B_m: Point, hrp: str = 'tsp', version: int = 0) -> str: + if B_scan is None or B_m is None: + raise ValueError('ERROR: Invalid data.') + ret = bech32_encode(hrp, [version] + convertbits(serP(B_scan) + serP(B_m), 8, 5), Encoding.BECH32M) + if decode(hrp, ret) == (None, None): + raise ValueError('ERROR: Invalid data.') + return ret + +def main(): + # 1️⃣ Re‑create the seed. + seed = get_seed() + key_material = generate_hardened_keys(seed) + # Receiver's scan and spend public key + B_scan = pubkey_point_gen_from_int(int_from_bytes(key_material['scan_priv_key'])) + B_spend = pubkey_point_gen_from_int(int_from_bytes(key_material['spend_priv_key'])) + sp = encode_silent_payment_address(B_scan, B_spend, 'sp', 0) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/config.json b/config.json index ee20315..44e1a94 100644 --- a/config.json +++ b/config.json @@ -1,33 +1,15 @@ { - "name": "Build your own!", - "short_description": "Extension building guide", - "tile": "/example/static/bitcoin-extension.png", - "min_lnbits_version": "1.0.0", - "donate": "donate@legend.lnbits.com", + "name": "Psssst! OnChain Wallet", + "short_description": "Privacy Wallet on LNBits", + "tile": "/silnt/static/bitcoin-wallet.png", + "min_lnbits_version": "v1.0.0", + "donate": "satoshi@bitaurus.net", "contributors": [ { - "name": "Ben Arc", - "uri": "mailto:ben@lnbits.com", + "name": "Ponthief", + "uri": "mailto:ponthief@bitaurus.net", "role": "Developer" - }, - { - "name": "DNI", - "uri": "https://github.com/dni", - "role": "Developer" - } - ], - "images": [ - { - "uri": "https://raw.githubusercontent.com/lnbits/example/main/static/1.png" - }, - { - "uri": "https://raw.githubusercontent.com/lnbits/example/main/static/2.png" - }, - { - "uri": "https://raw.githubusercontent.com/lnbits/example/main/static/3.png" } ], - "description_md": "https://raw.githubusercontent.com/lnbits/example/main/description.md", - "terms_and_conditions_md": "https://raw.githubusercontent.com/lnbits/example/main/toc.md", "license": "MIT" } diff --git a/crud.py b/crud.py index 608db57..6821013 100644 --- a/crud.py +++ b/crud.py @@ -1,21 +1,138 @@ -# crud.py is for communication with your extensions database +from typing import Optional, Tuple -# add your dependencies here -# from .models import createExample, Example from lnbits.db import Database +from lnbits.helpers import urlsafe_short_hash +from .models import Config, ConfigDb, WalletAccount -db = Database("ext_example") +from embit.descriptor import Descriptor, Key +from embit.descriptor.arguments import AllowedDerivation +from embit.networks import NETWORKS -# add your fnctions here +db = Database("ext_silnt") -# async def create_a_record(data: Example) -> createExample: -# example_id = urlsafe_short_hash() -# example = Example(id=example_id, **data.dict()) -# await db.insert("example.example", example) -# return example +async def create_silnt_wallet(wallet: WalletAccount) -> WalletAccount: + await db.insert("silnt.wallets", wallet) + return wallet -# async def get_a_record(example_id: str) -> Optional[Example]: -# return await db.fetchone( -# "SELECT * FROM example.example WHERE id = :id", {"id": example_id}, Example + +async def get_silnt_wallet(wallet_id: str) -> Optional[WalletAccount]: + return await db.fetchone( + "SELECT * FROM silnt.wallets WHERE id = :id", + {"id": wallet_id}, + WalletAccount, + ) + + +async def get_silnt_wallets(user: str, network: str) -> list[WalletAccount]: + # title, id, sp_address, hr_address, balance, network, created_at, last_height + return await db.fetchall( + """ + SELECT * FROM silnt.wallets + WHERE "user" = :user AND network = :network + """, + {"user": user, "network": network}, + WalletAccount, + ) + + +async def delete_silnt_wallet(wallet_id: str) -> None: + await db.execute( + "DELETE FROM silnt.wallets WHERE id = :id", + {"id": wallet_id}, + ) + +async def delete_utxos_for_wallet(wallet_id: str) -> None: + await db.execute( + "DELETE FROM silnt.utxos WHERE wallet_id = :wallet_id", + {"wallet_id": wallet_id}, + ) + +# async def get_fresh_address(wallet_id: str) -> Optional[Address]: +# # todo: move logic to views_api after satspay refactoring +# wallet = await get_silnt_wallet(wallet_id) + +# if not wallet: +# return None + +# wallet_addresses = await get_addresses(wallet_id) +# receive_addresses = list( +# filter( +# lambda addr: addr.branch_index == 0 and addr.has_activity, wallet_addresses +# ) # ) +# last_receive_index = ( +# receive_addresses.pop().address_index if receive_addresses else -1 +# ) +# address_index = ( +# last_receive_index +# if last_receive_index > wallet.address_no +# else wallet.address_no +# ) + +# address = await get_address_at_index(wallet_id, 0, address_index + 1) + +# if not address: +# addresses = await create_fresh_addresses( +# wallet_id, address_index + 1, address_index + 2 +# ) +# address = addresses.pop() + +# wallet.address_no = address_index + 1 +# await update_silnt_wallet(wallet) + +# return address + + +async def get_sp_address(wallet_id: str) -> str: + return await db.fetchall( + """ + SELECT sp_address FROM silnt.wallets WHERE wallet = :wallet + """, + {"wallet": wallet_id}, + str, + ) + +async def get_hr_address(wallet_id: str) -> str: + return await db.fetchall( + """ + SELECT hr_address FROM silnt.wallets WHERE wallet = :wallet + """, + {"wallet": wallet_id}, + str, + ) + + +async def update_hr_address(wallet_id: str, hr_address: str) -> Optional[WalletAccount]: + await db.execute(f"UPDATE silnt.wallets SET hr_address = :hra WHERE id = :wid", {"hra" : hr_address, "wid": wallet_id}) + return await db.fetchone( + "SELECT * FROM silnt.wallets WHERE id = :wid", {"wid": wallet_id}, + WalletAccount + ) +async def update_last_height(wallet_id: str, last_height: int) -> Optional[WalletAccount]: + await db.execute(f"UPDATE silnt.wallets SET last_height = :lh WHERE id = :wid", {"lh" : last_height, "wid": wallet_id}) + return await db.fetchone( + "SELECT * FROM silnt.wallets WHERE id = :wid", {"wid": wallet_id}, + WalletAccount + ) +async def create_config(user: str) -> Config: + config = Config() + await db.insert("silnt.config", ConfigDb(user=user, json_data=config)) + return config + + +async def update_config(config: Config, user: str) -> Config: + _config = ConfigDb(user=user, json_data=config) + await db.update("silnt.config", _config, """WHERE "user" = :user""") + return config + + +async def get_config(user: str) -> Config: + _config = await db.fetchone( + """SELECT * FROM silnt.config WHERE "user" = :user""", + {"user": user}, + ConfigDb, + ) + if not _config: + return await create_config(user) + return _config.json_data diff --git a/helpers/curve.py b/helpers/curve.py new file mode 100644 index 0000000..8d178a7 --- /dev/null +++ b/helpers/curve.py @@ -0,0 +1,187 @@ +import random +import hmac +import os +import hashlib +from enum import Enum +from typing import Optional, Tuple +from binascii import unhexlify +from ecdsa import SigningKey, SECP256k1 +# Elliptic curve parameters +p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F +n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 +G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, + 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8) + +# Points are tuples of X and Y coordinates +# the point at infinity is represented by the None keyword +Point = Tuple[int, int] + +class Encoding(Enum): + """Enumeration type to list the various supported encodings.""" + BECH32 = 1 + BECH32M = 2 + +CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" +BECH32M_CONST = 0x2bc830a3 + + +# Get x coordinate from a point +def x(P: Point) -> int: + return P[0] + + +# Get y coordinate from a point +def y(P: Point) -> int: + return P[1] + +# ser256(p): serializes the integer p as a 32-byte sequence, most significant byte first. +def ser256(p: int) -> bytes: + return p.to_bytes(32, 'big') + +# serP(P): serializes the coordinate pair P = (x,y) as a byte sequence using SEC1's compressed form: +# (0x02 or 0x03) || ser256(x), where the header byte depends on the parity of the omitted Y coordinate. +def serP(P: Point) -> bytes: + x_bytes = ser256(int_from_bytes(bytes_from_point(P))) + prefix = b'\x02' if has_even_y(P) else b'\x03' # Determine the parity of y to choose the prefix + return prefix + x_bytes + +# Get an int from bytes +def int_from_bytes(b: bytes) -> int: + return int.from_bytes(b, byteorder="big") + +# Point addition +def point_add(P1: Optional[Point], P2: Optional[Point]) -> Optional[Point]: + if P1 is None: + return P2 + if P2 is None: + return P1 + if (x(P1) == x(P2)) and (y(P1) != y(P2)): + return None + if P1 == P2: + lam = (3 * x(P1) * x(P1) * pow(2 * y(P1), p - 2, p)) % p + else: + lam = ((y(P2) - y(P1)) * pow(x(P2) - x(P1), p - 2, p)) % p + x3 = (lam * lam - x(P1) - x(P2)) % p + return x3, (lam * (x(P1) - x3) - y(P1)) % p + +# Point multiplication +def point_mul(P: Optional[Point], d: int) -> Optional[Point]: + R = None + for i in range(256): + if (d >> i) & 1: + R = point_add(R, P) + P = point_add(P, P) + return R + +# Check if a point has even y coordinate +def has_even_y(P: Point) -> bool: + return y(P) % 2 == 0 + +# Get bytes from an int +def bytes_from_int(a: int) -> bytes: + return a.to_bytes(32, byteorder="big") + +# Get bytes from a point +def bytes_from_point(P: Point) -> bytes: + return bytes_from_int(x(P)) + +# Get bytes from a hex +# def bytes_from_hex(a: str) -> bytes: +# return unhexlify(a) + + +def convertbits(data: bytes, frombits: int, tobits: int, pad: bool = True) -> Optional[list[int]]: + """General power-of-2 base conversion.""" + acc = 0 + bits = 0 + ret = [] + maxv = (1 << tobits) - 1 + max_acc = (1 << (frombits + tobits - 1)) - 1 + for value in data: + if value < 0 or (value >> frombits): + return None + acc = ((acc << frombits) | value) & max_acc + bits += frombits + while bits >= tobits: + bits -= tobits + ret.append((acc >> bits) & maxv) + if pad: + if bits: + ret.append((acc << (tobits - bits)) & maxv) + elif bits >= frombits or ((acc << (tobits - bits)) & maxv): + return None + return ret + +# Generate public key (as a point) from an int +def pubkey_point_gen_from_int(seckey: int) -> Point: + P = point_mul(G, seckey) + assert P is not None + return P + +def bech32_decode(bech: str) -> Tuple[Optional[str], Optional[list[int]], Optional[Encoding]]: + """Validate a Bech32m string, and determine HRP and data.""" + if ((any(ord(x) < 33 or ord(x) > 126 for x in bech)) or + (bech.lower() != bech and bech.upper() != bech)): + return (None, None, None) + bech = bech.lower() + pos = bech.rfind('1') + if pos < 1 or pos + 7 > len(bech) or len(bech) > 117: + return (None, None, None) + if not all(x in CHARSET for x in bech[pos+1:]): + return (None, None, None) + hrp = bech[:pos] + data = [CHARSET.find(x) for x in bech[pos+1:]] + spec = bech32_verify_checksum(hrp, data) + if spec is None: + return (None, None, None) + return (hrp, data[:-6], spec) + +def bech32_polymod(values: list[int]) -> int: + """Internal function that computes the Bech32 checksum.""" + generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3] + chk = 1 + for value in values: + top = chk >> 25 + chk = (chk & 0x1ffffff) << 5 ^ value + for i in range(5): + chk ^= generator[i] if ((top >> i) & 1) else 0 + return chk + +def bech32_hrp_expand(hrp: str) -> list[int]: + """Expand the HRP into values for checksum computation.""" + return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 31 for x in hrp] + +def bech32_verify_checksum(hrp: str, data: list[int]) -> Optional[Encoding]: + """Verify a checksum given HRP and converted data characters.""" + const = bech32_polymod(bech32_hrp_expand(hrp) + data) + if const == 1: + return Encoding.BECH32 + if const == BECH32M_CONST: + return Encoding.BECH32M + return None + +def decode(hrp: str, addr: str) -> Tuple[Optional[int], Optional[list[int]]]: + """Decode a segwit address.""" + hrpgot, data, _ = bech32_decode(addr) + if hrpgot != hrp: + return (None, None) + decoded = convertbits(data[1:], 5, 8, False) if data else None + if decoded is None or len(decoded) < 2 or len(decoded) > 71: + return (None, None) + if data[0] > 16: + return (None, None) + if data[0] == 0 and len(decoded) != 66: + return (None, None) + return (data[0], decoded) + +def bech32_create_checksum(hrp: str, data: list[int], spec: Encoding) -> list[int]: + """Compute the checksum values given HRP and data.""" + values = bech32_hrp_expand(hrp) + data + const = BECH32M_CONST if spec == Encoding.BECH32M else 1 + polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ const + return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)] + +def bech32_encode(hrp: str, data: list[int], spec: Encoding) -> str: + """Compute a Bech32 string given HRP and data values.""" + combined = data + bech32_create_checksum(hrp, data, spec) + return hrp + '1' + ''.join([CHARSET[d] for d in combined]) \ No newline at end of file diff --git a/helpers/wallet.py b/helpers/wallet.py new file mode 100644 index 0000000..313b3d8 --- /dev/null +++ b/helpers/wallet.py @@ -0,0 +1,61 @@ +from embit import bip32 +from embit import bip39 +from embit.networks import NETWORKS +from binascii import hexlify +from .curve import bech32_encode, convertbits, serP, decode, Encoding +from .curve import pubkey_point_gen_from_int, int_from_bytes, Point +from loguru import logger +from lnbits.utils.crypto import AESCipher + +def get_seed(mnemonic) -> bytes: + """ + Re‑creates the BIP‑39 seed from the hard‑coded mnemonic. + Returns the 64‑byte seed (as `bytes`). + """ + seed = bip39.mnemonic_to_seed(mnemonic) + return seed + +def generate_hardened_keys(seed) -> dict: + root = bip32.HDKey.from_seed(seed, version=NETWORKS["main"]["xprv"]) + scan_private_key = root.derive("m/352h/0h/0h/1h/0").key.secret + spend_private_key = root.derive("m/352h/0h/0h/0h/0").key.secret + scank = root.derive("m/352h/0h/0h/1h/0").key.secret + spendk = root.derive("m/352h/0h/0h/0h/0") + # Store the keys in a dictionary + key_material = { + 'scan_priv_key': scan_private_key, + 'spend_priv_key': spend_private_key, + 'scank': hexlify(scank).decode(), + 'spendk': spendk.get_public_key() + } + return key_material + +def encode_silent_payment_address(B_scan: Point, B_m: Point, hrp: str = 'tsp', version: int = 0) -> str: + if B_scan is None or B_m is None: + raise ValueError('ERROR: Invalid data.') + ret = bech32_encode(hrp, [version] + convertbits(serP(B_scan) + serP(B_m), 8, 5), Encoding.BECH32M) + if decode(hrp, ret) == (None, None): + raise ValueError('ERROR: Invalid data.') + return ret + +def generate_silent_wallet_address(mnemonic) -> tuple: + seed = get_seed(mnemonic) + key_material = generate_hardened_keys(seed) + # Receiver's scan and spend public key + B_scan = pubkey_point_gen_from_int(int_from_bytes(key_material['scan_priv_key'])) + B_spend = pubkey_point_gen_from_int(int_from_bytes(key_material['spend_priv_key'])) + sp = encode_silent_payment_address(B_scan, B_spend, 'sp', 0) + return (str(sp), str(key_material['scank']), str(key_material['spendk'])) + +def decrypt_mnemonic(m: str | None = None, k: str | None = None, urlsafe: bool = False) -> str | None: + """ + Decrypt message with the secret key + + Args: + m: Message to decrypt + k: Key used to decrypt + urlsafe: Whether the message uses URL-safe base64 encoding + """ + if not m: + return None + return AESCipher(key=k).decrypt(m, urlsafe=urlsafe) \ No newline at end of file diff --git a/manifest.json b/manifest.json index e7c1f9e..4d23b61 100644 --- a/manifest.json +++ b/manifest.json @@ -1,9 +1,9 @@ { "repos": [ { - "id": "example", + "id": "silnt", "organisation": "lnbits", - "repository": "example" + "repository": "silnt" } ] } diff --git a/migrations.py b/migrations.py index 9d37d97..abcffcb 100644 --- a/migrations.py +++ b/migrations.py @@ -1,12 +1,39 @@ -# migrations.py is for building your database +async def m001_initial(db): + """ + Initial wallet table. + """ + await db.execute( + f""" + CREATE TABLE silnt.wallets ( + id TEXT NOT NULL PRIMARY KEY, + "user" TEXT, + network TEXT DEFAULT 'mainnet', + title TEXT NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT {db.timestamp_now}, + updated_at TIMESTAMPTZ NOT NULL DEFAULT {db.timestamp_now}, + scan_secret TEXT NOT NULL, + spend_key TEXT NOT NULL, + sp_address TEXT NOT NULL, + hr_address TEXT NOT NULL, + last_height INTEGER, + balance {db.big_int} + ); + """ + ) + + await db.execute( + f""" + CREATE TABLE silnt.utxos ( + txid TEXT NOT NULL PRIMARY KEY, + vout SMALLINT NOT NULL, + amount {db.big_int} NOT NULL, + priv_key_tweak TEXT NOT NULL, + pub_key TEXT NOT NULL, + timestamp TIMESTAMP NOT NULL, + utxo_state TEXT NOT NULL, + label TEXT NOT NULL, + wallet_id TEXT NOT NULL + ); + """ + ) -# async def m001_initial(db): -# await db.execute( -# f""" -# CREATE TABLE example.example ( -# id TEXT PRIMARY KEY, -# wallet TEXT NOT NULL, -# time TIMESTAMP NOT NULL DEFAULT {db.timestamp_now} -# ); -# """ -# ) diff --git a/models.py b/models.py index a9e665b..4f1853b 100644 --- a/models.py +++ b/models.py @@ -1,10 +1,90 @@ +from typing import Optional + +from fastapi import Query from pydantic import BaseModel -class Example(BaseModel): +class CreateWallet(BaseModel): + mnemonic: str = Query("") + title: str = Query("") + network: str = "mainnet" + hr_address: str = Query("") + last_height: str = Query("") + + +class WalletAccount(BaseModel): id: str - wallet: str + user: str + title: str + balance: int + network: str = "mainnet" + scan_secret: str + spend_key: str + sp_address: str + hr_address: str + last_height: int + +class UTXORecord(BaseModel): + txid: str + vout: str + amount: int + priv_key_tweak: str + pub_key: str + timestamp: int + utxo_state: str + label: str + wallet_id: str + + +# class Address(BaseModel): +# id: str +# address: str +# wallet: str +# amount: int = 0 +# branch_index: int = 0 +# address_index: int +# note: Optional[str] = None +# has_activity: bool = False + + +# class TransactionInput(BaseModel): +# tx_id: str +# vout: int +# amount: int +# address: str +# branch_index: int +# address_index: int +# wallet: str +# tx_hex: str + + +# class TransactionOutput(BaseModel): +# amount: int +# address: str +# branch_index: Optional[int] = None +# address_index: Optional[int] = None +# wallet: Optional[str] = None + + + + +# class ExtractTx(BaseModel): +# tx_hex = "" +# network = "Mainnet" + + +# class SignedTransaction(BaseModel): +# tx_hex: Optional[str] + # tx_json: Optional[str] + + +class Config(BaseModel): + mempool_endpoint = "https://mempool.space" + sats_denominated = True + network = "mainnet" + +class ConfigDb(BaseModel): + user: str + json_data: Config -class CreateExample(BaseModel): - wallet: str diff --git a/pyproject.toml b/pyproject.toml index d475b4a..707ca61 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,16 @@ [project] -name = "lnbits-example" -version = "0.0.0" +name = "silnt" +version = "0.1.0" requires-python = ">=3.10,<3.13" -description = "LNbits, free and open-source Lightning wallet and accounts system." -authors = [{ name = "Alan Bits", email = "alan@lnbits.com" }] -urls = { Homepage = "https://lnbits.com", Repository = "https://github.com/lnbits/example" } +description = "Silent Payments OnChain Wallet for LNBits" +authors = [{ name = "Bitaurus", email = "ponthief@bitaurus.net" }] +urls = { Homepage = "https://bitaurus.net", Repository = "https://github.com/ponthief/silnt" } -dependencies = [ "lnbits>1" ] +dependencies = [ + "bitcoinlib>=0.6.12.1", + "embit>=0.8.0", + "lnbits>1", +] [tool.uv] dev-dependencies = [ @@ -30,6 +34,7 @@ warn_untyped_fields = true [[tool.mypy.overrides]] module = [ + "embit.*", "lnbits.*", "lnurl.*", "loguru.*", diff --git a/static/1.png b/static/1.png deleted file mode 100644 index 10b367334be71a7b56ab62dace6fea8b952e9d97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198146 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�_eGgMwZ+EyT-_0ec*kGfq~Z6 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 z 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

*PM@tBcBE-hR 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

M; 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 wl.id === walletId) + return wallet ? wallet.title : 'unknown' + }, + getFilteredAddresses: function () { + const selectedWalletId = this.selectedWallet?.id + const filter = this.filterValues || [] + const includeChangeAddrs = filter.includes('Show Change Addresses') + const includeGapAddrs = filter.includes('Show Gap Addresses') + const excludeNoAmount = filter.includes('Only With Amount') + + const walletsLimit = (this.accounts || []).reduce((r, w) => { + r[`_${w.id}`] = w.address_no + return r + }, {}) + + const fAddresses = this.addresses.filter( + a => + (includeChangeAddrs || !a.isChange) && + (includeGapAddrs || + a.isChange || + a.addressIndex <= walletsLimit[`_${a.wallet}`]) && + !(excludeNoAmount && a.amount === 0) && + (!selectedWalletId || a.wallet === selectedWalletId) + ) + return fAddresses + }, + + scanAddress: async function (addressData) { + this.$emit('scan:address', addressData) + }, + showAddressDetails: function (addressData) { + this.$emit('show-address-details', addressData) + }, + searchInTab: function (tab, value) { + this.$emit('search:tab', {tab, value}) + }, + updateNoteForAddress: async function (addressData, note) { + this.$emit('update:note', {addressId: addressData.id, note}) + } + }, + + created: async function () {} +}) diff --git a/static/components/fee-rate.js b/static/components/fee-rate.js new file mode 100644 index 0000000..8b9725a --- /dev/null +++ b/static/components/fee-rate.js @@ -0,0 +1,61 @@ +window.app.component('fee-rate', { + name: 'fee-rate', + template: '#fee-rate', + delimiters: ['${', '}'], + + props: ['rate', 'fee-value', 'sats-denominated', 'mempool-endpoint'], + + computed: { + feeRate: { + get: function () { + return this['rate'] + }, + set: function (value) { + this.$emit('update:rate', +value) + } + } + }, + + data: function () { + return { + recommededFees: { + fastestFee: 1, + halfHourFee: 1, + hourFee: 1, + economyFee: 1, + minimumFee: 1 + } + } + }, + + methods: { + satBtc(val, showUnit = true) { + return satOrBtc(val, showUnit, this.satsDenominated) + }, + + refreshRecommendedFees: async function () { + const fn = async () => { + const { + bitcoin: {fees: feesAPI} + } = mempoolJS({ + hostname: this.mempoolEndpoint + }) + return feesAPI.getFeesRecommended() + } + this.recommededFees = await retryWithDelay(fn) + }, + getFeeRateLabel: function (feeRate) { + const fees = this.recommededFees + if (feeRate >= fees.fastestFee) return `High Priority (${feeRate} sat/vB)` + if (feeRate >= fees.halfHourFee) + return `Medium Priority (${feeRate} sat/vB)` + if (feeRate >= fees.hourFee) return `Low Priority (${feeRate} sat/vB)` + return `No Priority (${feeRate} sat/vB)` + } + }, + + created: async function () { + await this.refreshRecommendedFees() + this.feeRate = this.recommededFees.halfHourFee + } +}) diff --git a/static/components/history.js b/static/components/history.js new file mode 100644 index 0000000..6ab3568 --- /dev/null +++ b/static/components/history.js @@ -0,0 +1,96 @@ +window.app.component('history', { + name: 'history', + template: '#history', + delimiters: ['${', '}'], + + props: ['history', 'mempool-endpoint', 'sats-denominated', 'filter'], + data: function () { + return { + historyTable: { + columns: [ + { + name: 'expand', + align: 'left', + label: '' + }, + { + name: 'status', + align: 'left', + label: 'Status' + }, + { + name: 'amount', + align: 'left', + label: 'Amount', + field: 'amount', + sortable: true + }, + { + name: 'address', + align: 'left', + label: 'Address', + field: 'address', + sortable: true + }, + { + name: 'date', + align: 'left', + label: 'Date', + field: 'date', + sortable: true + }, + { + name: 'txId', + field: 'txId' + } + ], + exportColums: [ + { + label: 'Action', + field: 'action' + }, + { + label: 'Date&Time', + field: 'date' + }, + { + label: 'Amount', + field: 'amount' + }, + { + label: 'Fee', + field: 'fee' + }, + { + label: 'Transaction Id', + field: 'txId' + } + ], + pagination: { + rowsPerPage: 0 + } + } + } + }, + + methods: { + satBtc(val, showUnit = true) { + return satOrBtc(val, showUnit, this.satsDenominated) + }, + getFilteredAddressesHistory: function () { + return this.history.filter(a => (!a.isChange || a.sent) && !a.isSubItem) + }, + exportHistoryToCSV: function () { + const history = this.getFilteredAddressesHistory().map(a => ({ + ...a, + action: a.sent ? 'Sent' : 'Received' + })) + LNbits.utils.exportCSV( + this.historyTable.exportColums, + history, + 'address-history' + ) + } + }, + created: async function () {} +}) diff --git a/static/components/my-checkbox.js b/static/components/my-checkbox.js new file mode 100644 index 0000000..a015776 --- /dev/null +++ b/static/components/my-checkbox.js @@ -0,0 +1,14 @@ +window.app.component('my-checkbox', { + name: 'my-checkbox', + template: '#my-checkbox', + delimiters: ['${', '}'], + data() { + return {checked: false, title: 'Check me'} + }, + methods: { + check() { + this.checked = !this.checked + console.log('### checked', this.checked) + } + } +}) diff --git a/static/components/payment.js b/static/components/payment.js new file mode 100644 index 0000000..b1e9cd3 --- /dev/null +++ b/static/components/payment.js @@ -0,0 +1,419 @@ +window.app.component('payment', { + name: 'payment', + template: '#payment', + delimiters: ['${', '}'], + + props: [ + 'accounts', + 'addresses', + 'utxos', + 'mempool-endpoint', + 'sats-denominated', + 'serial-signer-ref', + 'adminkey', + 'network' + ], + watch: { + immediate: true, + accounts() { + this.updateChangeAddress() + }, + addresses() { + this.updateChangeAddress() + } + }, + + data: function () { + return { + DUST_LIMIT: 546, + tx: null, + psbtBase64: null, + psbtBase64Signed: null, + signedTx: null, + signedTxHex: null, + sentTxId: null, + signedTxId: null, + sendToList: [{address: '', amount: undefined}], + changeWallet: null, + changeAddress: {}, + showCustomFee: false, + showCoinSelect: false, + showChecking: false, + showChange: false, + showPsbt: false, + showFinalTx: false, + feeRate: 1 + } + }, + + computed: { + txSize: function () { + const tx = this.createTx() + return Math.round(txSize(tx)) + }, + txSizeNoChange: function () { + const tx = this.createTx(true) + return Math.round(txSize(tx)) + }, + feeValue: function () { + return this.feeRate * this.txSize + }, + selectedAmount: function () { + return this.utxos + .filter(utxo => utxo.selected) + .reduce((t, a) => t + (a.amount || 0), 0) + }, + changeAmount: function () { + return ( + this.selectedAmount - this.totalPayedAmount - this.feeRate * this.txSize + ) + }, + balance: function () { + return this.utxos.reduce((t, a) => t + (a.amount || 0), 0) + }, + totalPayedAmount: function () { + return this.sendToList.reduce((t, a) => t + (a.amount || 0), 0) + } + }, + + methods: { + satBtc(val, showUnit = true) { + return satOrBtc(val, showUnit, this.satsDenominated) + }, + clearState: function () { + this.psbtBase64 = null + this.psbtBase64Signed = null + this.signedTx = null + this.signedTxHex = null + this.signedTxId = null + this.sendToList = [{address: '', amount: undefined}] + this.showChecking = false + this.showPsbt = false + this.showFinalTx = false + }, + checkAndSend: async function () { + this.showChecking = true + try { + if (!this.serialSignerRef.isConnected()) { + this.$q.notify({ + type: 'warning', + message: 'Please connect to a Signing device first!', + timeout: 10000 + }) + return + } + const p2trUtxo = this.utxos.find( + u => u.selected && u.accountType === 'p2tr' + ) + if (p2trUtxo && !this.serialSignerRef.isTaprootSupported()) { + this.$q.notify({ + type: 'warning', + message: 'Taproot Signing not supported for this device!', + caption: 'Please manually deselect the Taproot UTXOs', + timeout: 10000 + }) + return + } + if (!this.serialSignerRef.isAuthenticated()) { + await this.serialSignerRef.hwwShowPasswordDialog() + const authenticated = await this.serialSignerRef.isAuthenticating() + if (!authenticated) return + } + + await this.createPsbt() + + if (this.psbtBase64) { + const txData = { + inputs: this.tx.inputs, + outputs: this.tx.outputs, + feeRate: this.tx.fee_rate, + feeValue: this.feeValue + } + await this.serialSignerRef.hwwSendPsbt(this.psbtBase64, txData) + await this.serialSignerRef.isSendingPsbt() + } + } catch (error) { + this.$q.notify({ + type: 'warning', + message: 'Cannot check and sign transaction!', + caption: `${error}`, + timeout: 10000 + }) + } finally { + this.showChecking = false + this.psbtBase64 = null + } + }, + showPsbtDialog: async function () { + try { + const valid = await this.$refs.paymentFormRef.validate() + if (!valid) return + + const data = await this.createPsbt() + if (data) { + this.showPsbt = true + } + } catch (error) { + this.$q.notify({ + type: 'warning', + message: 'Failed to create PSBT!', + caption: `${error}`, + timeout: 10000 + }) + } + }, + createPsbt: async function () { + try { + this.tx = this.createTx() + for (const input of this.tx.inputs) { + input.tx_hex = await this.fetchTxHex(input.tx_id) + } + + const changeOutput = this.tx.outputs.find(o => o.branch_index === 1) + if (changeOutput) changeOutput.amount = this.changeAmount + + const {data} = await LNbits.api.request( + 'POST', + '/watchonly/api/v1/psbt', + this.adminkey, + this.tx + ) + + this.psbtBase64 = data + return data + } catch (err) { + LNbits.utils.notifyApiError(err) + } + }, + createTx: function (excludeChange = false) { + const tx = { + fee_rate: this.feeRate, + masterpubs: this.accounts.map(w => ({ + id: w.id, + public_key: w.masterpub, + fingerprint: w.fingerprint + })) + } + tx.inputs = this.utxos + .filter(utxo => utxo.selected) + .map(mapUtxoToPsbtInput) + .sort((a, b) => + a.tx_id < b.tx_id ? -1 : a.tx_id > b.tx_id ? 1 : a.vout - b.vout + ) + + tx.outputs = this.sendToList.map(out => ({ + address: out.address, + amount: out.amount + })) + + if (!excludeChange) { + const change = this.createChangeOutput() + const diffAmount = this.selectedAmount - this.totalPayedAmount + if (diffAmount >= this.DUST_LIMIT) { + tx.outputs.push(change) + } + } + tx.tx_size = Math.round(txSize(tx)) + tx.inputs = _.shuffle(tx.inputs) + tx.outputs = _.shuffle(tx.outputs) + + return tx + }, + createChangeOutput: function () { + const change = this.changeAddress + const walletAcount = this.accounts.find(w => w.id === change.wallet) || { + meta: {} + } + + return { + address: change.address, + address_index: change.addressIndex, + branch_index: change.isChange ? 1 : 0, + wallet: walletAcount.id, + accountPath: walletAcount.meta.accountPath, + accountType: walletAcount.type + } + }, + selectChangeAddress: function (account) { + if (!account) this.changeAddress = '' + this.changeAddress = + this.addresses.find( + a => a.wallet === account.id && a.isChange && !a.hasActivity + ) || {} + }, + updateChangeAddress: function () { + if (this.changeWallet) { + const changeAccount = (this.accounts || []).find( + w => w.id === this.changeWallet.id + ) + // change account deleted + if (!changeAccount) { + this.changeWallet = this.accounts[0] + } + } else { + this.changeWallet = this.accounts[0] + } + this.selectChangeAddress(this.changeWallet) + }, + updateSignedPsbt: async function (psbtBase64) { + try { + this.showChecking = true + this.psbtBase64Signed = psbtBase64 + + const data = await this.extractTxFromPsbt(psbtBase64) + this.showFinalTx = true + if (data) { + this.signedTx = JSON.parse(data.tx_json) + this.signedTxHex = data.tx_hex + } else { + this.signedTx = null + this.signedTxHex = null + } + } finally { + this.showChecking = false + } + }, + updateSignedTx: async function (txData) { + try { + this.showChecking = true + + const data = await this.extractTx(txData.serializedTx) + this.showFinalTx = true + if (data) { + this.signedTx = data.tx_json + this.signedTx.fee = txData.feeValue + this.signedTxHex = txData.serializedTx + } else { + this.signedTx = null + this.signedTxHex = null + } + } finally { + this.showChecking = false + } + }, + + fetchUtxoHexForPsbt: async function (psbtBase64) { + if (this.tx?.inputs && this.tx?.inputs.length) return this.tx.inputs + + const {data: psbtUtxos} = await LNbits.api.request( + 'PUT', + '/watchonly/api/v1/psbt/utxos', + this.adminkey, + {psbtBase64} + ) + + const inputs = [] + for (const utxo of psbtUtxos) { + const txHex = await this.fetchTxHex(utxo.tx_id) + inputs.push({tx_hex: txHex}) + } + return inputs + }, + extractTxFromPsbt: async function (psbtBase64) { + try { + const inputs = await this.fetchUtxoHexForPsbt(psbtBase64) + + const {data} = await LNbits.api.request( + 'PUT', + '/watchonly/api/v1/psbt/extract', + this.adminkey, + { + psbtBase64, + inputs, + network: this.network + } + ) + return data + } catch (error) { + this.$q.notify({ + type: 'warning', + message: 'Cannot finalize PSBT!', + caption: `${error}`, + timeout: 10000 + }) + LNbits.utils.notifyApiError(error) + } + }, + extractTx: async function (txHex) { + try { + const {data} = await LNbits.api.request( + 'PUT', + '/watchonly/api/v1/tx/extract', + this.adminkey, + { + tx_hex: txHex, + network: this.network + } + ) + return data + } catch (error) { + this.$q.notify({ + type: 'warning', + message: 'Cannot extract transaction for tx hex!', + caption: `${error}`, + timeout: 10000 + }) + LNbits.utils.notifyApiError(error) + } + }, + broadcastTransaction: async function () { + try { + const {data} = await LNbits.api.request( + 'POST', + '/watchonly/api/v1/tx', + this.adminkey, + {tx_hex: this.signedTxHex} + ) + this.sentTxId = data + + this.$q.notify({ + type: 'positive', + message: 'Transaction broadcasted!', + caption: `${data}`, + timeout: 10000 + }) + + this.clearState() + this.$emit('broadcast-done', this.sentTxId) + } catch (error) { + this.sentTxId = null + this.$q.notify({ + type: 'warning', + message: 'Failed to broadcast!', + caption: `${error}`, + timeout: 10000 + }) + } finally { + this.showFinalTx = false + } + }, + fetchTxHex: async function (txId) { + const { + bitcoin: {transactions: transactionsAPI} + } = mempoolJS({ + hostname: this.mempoolEndpoint + }) + + try { + const response = await transactionsAPI.getTxHex({txid: txId}) + return response + } catch (error) { + this.$q.notify({ + type: 'warning', + message: `Failed to fetch transaction details for tx id: '${txId}'`, + timeout: 10000 + }) + LNbits.utils.notifyApiError(error) + throw error + } + }, + handleOutputsChange: function () { + this.$refs.utxoList.refreshUtxoSelection(this.totalPayedAmount) + }, + getTotalPaymentAmount: function () { + return this.sendToList.reduce((t, a) => t + (a.amount || 0), 0) + } + }, + + created: async function () {} +}) diff --git a/static/components/seed-input.js b/static/components/seed-input.js new file mode 100644 index 0000000..e02b37d --- /dev/null +++ b/static/components/seed-input.js @@ -0,0 +1,100 @@ +window.app.component('seed-input', { + name: 'seed-input', + template: '#seed-input', + delimiters: ['${', '}'], + + computed: { + actualPosition: function () { + return this.words[this.currentPosition].position + } + }, + + data: function () { + return { + wordCountOptions: ['12', '15', '18', '21', '24'], + wordCount: 24, + words: [], + currentPosition: 0, + stringOptions: [], + options: [], + currentWord: '', + done: false + } + }, + + methods: { + filterFn(val, update, abort) { + update(() => { + const needle = val.toLocaleLowerCase() + this.options = this.stringOptions + .filter(v => v.toLocaleLowerCase().indexOf(needle) != -1) + .sort((a, b) => { + if (a.startsWith(needle)) { + if (b.startsWith(needle)) { + return a - b + } + return -1 + } else { + if (b.startsWith(needle)) { + return 1 + } + return a - b + } + }) + }) + }, + initWords() { + const words = [] + for (let i = 1; i <= this.wordCount; i++) { + words.push({ + position: i, + value: '' + }) + } + this.currentPosition = 0 + this.words = _.shuffle(words) + }, + setModel(val) { + this.currentWord = val + this.words[this.currentPosition].value = this.currentWord + }, + nextPosition() { + if (this.currentPosition < this.wordCount - 1) { + this.currentPosition++ + } + this.currentWord = this.words[this.currentPosition].value + }, + previousPosition() { + if (this.currentPosition > 0) { + this.currentPosition-- + } + this.currentWord = this.words[this.currentPosition].value + }, + seedInputDone() { + const badWordPositions = this.words + .filter(w => !w.value || !this.stringOptions.includes(w.value)) + .map(w => w.position) + if (badWordPositions.length) { + this.$q.notify({ + timeout: 10000, + type: 'warning', + message: + 'The seed has incorrect words. Please check at these positions: ', + caption: 'Position: ' + badWordPositions.join(', ') + }) + return + } + const mnemonic = this.words + .sort((a, b) => a.position - b.position) + .map(w => w.value) + .join(' ') + this.$emit('on-seed-input-done', mnemonic) + this.done = true + } + }, + + created: async function () { + this.stringOptions = bip39WordList + this.initWords() + } +}) diff --git a/static/components/send-to.js b/static/components/send-to.js new file mode 100644 index 0000000..f8cba5f --- /dev/null +++ b/static/components/send-to.js @@ -0,0 +1,69 @@ +window.app.component('send-to', { + name: 'send-to', + template: '#send-to', + delimiters: ['${', '}'], + + props: ['data', 'tx-size', 'selected-amount', 'fee-rate', 'sats-denominated'], + + computed: { + dataLocal: { + get: function () { + return this.data + }, + set: function (value) { + this.$emit('update:data', value) + } + } + }, + + data: function () { + return { + DUST_LIMIT: 546, + paymentTable: { + columns: [ + { + name: 'data', + align: 'left' + } + ], + pagination: { + rowsPerPage: 10 + }, + filter: '' + } + } + }, + + methods: { + satBtc(val, showUnit = true) { + return satOrBtc(val, showUnit, this.satsDenominated) + }, + addPaymentAddress: function () { + this.dataLocal.push({address: '', amount: undefined}) + this.handleOutputsChange() + }, + deletePaymentAddress: function (v) { + const index = this.dataLocal.indexOf(v) + if (index !== -1) { + this.dataLocal.splice(index, 1) + } + this.handleOutputsChange() + }, + + sendMaxToAddress: function (paymentAddress = {}) { + const feeValue = this.feeRate * this.txSize + const inputAmount = this.selectedAmount + const currentAmount = Math.max(0, paymentAddress.amount || 0) + const payedAmount = this.getTotalPaymentAmount() - currentAmount + paymentAddress.amount = Math.max(0, inputAmount - payedAmount - feeValue) + }, + handleOutputsChange: function () { + this.$emit('update:outputs') + }, + getTotalPaymentAmount: function () { + return this.dataLocal.reduce((t, a) => t + (a.amount || 0), 0) + } + }, + + created: async function () {} +}) diff --git a/static/components/utxo-list.js b/static/components/utxo-list.js new file mode 100644 index 0000000..545fdee --- /dev/null +++ b/static/components/utxo-list.js @@ -0,0 +1,146 @@ +window.app.component('utxo-list', { + name: 'utxo-list', + template: '#utxo-list', + delimiters: ['${', '}'], + + props: [ + 'utxos', + 'accounts', + 'selectable', + 'payed-amount', + 'sats-denominated', + 'mempool-endpoint', + 'filter' + ], + + data: function () { + return { + utxosTable: { + columns: [ + { + name: 'expand', + align: 'left', + label: '' + }, + { + name: 'selected', + align: 'left', + label: '', + selectable: true + }, + { + name: 'status', + align: 'center', + label: 'Status', + sortable: true + }, + { + name: 'address', + align: 'left', + label: 'Address', + field: 'address', + sortable: true + }, + { + name: 'amount', + align: 'left', + label: 'Amount', + field: 'amount', + sortable: true + }, + { + name: 'date', + align: 'left', + label: 'Date', + field: 'date', + sortable: true + }, + { + name: 'wallet', + align: 'left', + label: 'Account', + field: 'wallet', + sortable: true + } + ], + pagination: { + rowsPerPage: 10 + } + }, + utxoSelectionModes: [ + 'Manual', + 'Random', + 'Select All', + 'Smaller Inputs First', + 'Larger Inputs First' + ], + utxoSelectionMode: 'Random', + utxoSelectAmount: 0 + } + }, + + computed: { + columns: function () { + return this.utxosTable.columns.filter(c => + c.selectable ? this.selectable : true + ) + } + }, + + methods: { + satBtc(val, showUnit = true) { + return satOrBtc(val, showUnit, this.satsDenominated) + }, + getWalletName: function (walletId) { + const wallet = (this.accounts || []).find(wl => wl.id === walletId) + return wallet ? wallet.title : 'unknown' + }, + getTotalSelectedUtxoAmount: function () { + const total = (this.utxos || []) + .filter(u => u.selected) + .reduce((t, a) => t + (a.amount || 0), 0) + return total + }, + refreshUtxoSelection: function (totalPayedAmount) { + this.utxoSelectAmount = totalPayedAmount + this.applyUtxoSelectionMode() + }, + updateUtxoSelection: function () { + this.utxoSelectAmount = this.payedAmount + this.applyUtxoSelectionMode() + }, + applyUtxoSelectionMode: function () { + const mode = this.utxoSelectionMode + const isSelectAll = mode === 'Select All' + if (isSelectAll) { + this.utxos.forEach(u => (u.selected = true)) + return + } + + const isManual = mode === 'Manual' + if (isManual || !this.utxoSelectAmount) return + + this.utxos.forEach(u => (u.selected = false)) + + const isSmallerFirst = mode === 'Smaller Inputs First' + const isLargerFirst = mode === 'Larger Inputs First' + let selectedUtxos = this.utxos.slice() + if (isSmallerFirst || isLargerFirst) { + const sortFn = isSmallerFirst + ? (a, b) => a.amount - b.amount + : (a, b) => b.amount - a.amount + selectedUtxos.sort(sortFn) + } else { + // default to random order + selectedUtxos = _.shuffle(selectedUtxos) + } + selectedUtxos.reduce((total, utxo) => { + utxo.selected = total < this.utxoSelectAmount + total += utxo.amount + return total + }, 0) + } + }, + + created: async function () {} +}) diff --git a/static/components/wallet-config.js b/static/components/wallet-config.js new file mode 100644 index 0000000..ef653d0 --- /dev/null +++ b/static/components/wallet-config.js @@ -0,0 +1,66 @@ +window.app.component('wallet-config', { + name: 'wallet-config', + template: '#wallet-config', + delimiters: ['${', '}'], + + props: ['total', 'config-data', 'adminkey'], + emits: ['update:config-data'], + data: function () { + return { + networkOptions: ['Mainnet', 'Testnet'], + internalConfig: {}, + show: false + } + }, + + computed: { + config: { + get() { + return this.internalConfig + }, + set(value) { + value.isLoaded = true + this.internalConfig = JSON.parse(JSON.stringify(value)) + this.$emit( + 'update:config-data', + JSON.parse(JSON.stringify(this.internalConfig)) + ) + } + } + }, + + methods: { + satBtc(val, showUnit = true) { + return satOrBtc(val, showUnit, this.config.sats_denominated) + }, + updateConfig: async function () { + try { + const {data} = await LNbits.api.request( + 'PUT', + '/watchonly/api/v1/config', + this.adminkey, + this.config + ) + this.show = false + this.config = data + } catch (error) { + LNbits.utils.notifyApiError(error) + } + }, + getConfig: async function () { + try { + const {data} = await LNbits.api.request( + 'GET', + '/watchonly/api/v1/config', + this.adminkey + ) + this.config = data + } catch (error) { + LNbits.utils.notifyApiError(error) + } + } + }, + created: async function () { + await this.getConfig() + } +}) diff --git a/static/components/wallet-list.js b/static/components/wallet-list.js new file mode 100644 index 0000000..0eb59d5 --- /dev/null +++ b/static/components/wallet-list.js @@ -0,0 +1,254 @@ +window.app.component('wallet-list', { + name: 'wallet-list', + template: '#wallet-list', + delimiters: ['${', '}'], + + props: [ + 'adminkey', + 'inkey', + 'sats-denominated', + 'addresses', + 'network' + ], + data: function () { + return { + walletAccounts: [], + address: {}, + formDialog: { + show: false, + data: { + title: '', + hr_address: '', + last_height: '' + } + }, + updateDialog: { + show: false, + data: { + title: '', + hr_address: '', + last_height: '' + } + }, + showCreating: false, + showUpdating: false, + walletsTable: { + columns: [ + {name: 'id', align: 'left', label: 'ID', field: 'id'}, + { + name: 'title', + align: 'left', + label: 'Title', + field: 'title' + }, + { + name: 'hr_address', + align: 'left', + label: 'HR Address', + field: 'hr_address' + }, + { + name: 'last_height', + align: 'left', + label: 'Height', + field: 'last_height' + }, + { + name: 'balance', + align: 'left', + label: 'Balance', + field: 'balance' + } + ], + pagination: { + rowsPerPage: 10 + } + } + } + }, + + methods: { + satBtc(val, showUnit = true) { + return satOrBtc(val, showUnit, this.satsDenominated) + }, + addWalletAccount: async function () { + this.showCreating = true + const data = _.omit(this.formDialog.data, 'wallet') + data.network = this.network + data.mnemonic = CryptoJS.AES.encrypt(data.mnemonic, data.last_height).toString(); + await this.createWalletAccount(data) + this.showCreating = false + }, + updateWalletAccount: async function () { + this.showUpdating = true + const data = _.omit(this.updateDialog.data, 'wallet') + data.network = this.network + if (data.id) { + await this.updateHRAddressHeight(data) + } + this.showUpdating = false + }, + createWalletAccount: async function (data) { + try { + console.log(data) + const response = await LNbits.api.request( + 'POST', + '/silnt/api/v1/wallet', + this.adminkey, + data + ) + this.walletAccounts.push(mapWalletAccount(response.data)) + this.formDialog.show = false + + await this.refreshWalletAccounts() + } catch (error) { + LNbits.utils.notifyApiError(error) + } + Quasar.Notify.create({ + type: 'positive', + message: 'Silent Payment Wallet Added.' + }) + }, + updateWalletDialog(walletAccountId) { + var wallet = _.findWhere(this.walletAccounts, {id: walletAccountId}) + this.updateDialog.data = _.clone(wallet) + this.updateDialog.hr_address = this.updateDialog.data.hr_address + this.updateDialog.last_height = this.updateDialog.data.last_height + this.updateDialog.show = true + }, + updateHRAddressHeight: async function (data) { + try { + const response = await LNbits.api.request( + 'POST', + '/silnt/api/v1/wallet' + data.id, + this.adminkey, + data + ) + this.walletAccounts.push(mapWalletAccount(response.data)) + this.updateDialog.show = false + + await this.refreshWalletAccounts() + } catch (error) { + LNbits.utils.notifyApiError(error) + } + Quasar.Notify.create({ + type: 'positive', + message: 'Wallet updated.' + }) + }, + deleteWalletDialog: function (walletAccountId) { + LNbits.utils + .confirmDialog( + 'Are you sure you want to delete this Silnt wallet?' + ) + .onOk(async () => { + try { + await LNbits.api.request( + 'DELETE', + '/silnt/api/v1/wallet/' + walletAccountId, + this.adminkey + ) + this.walletAccounts = _.reject(this.walletAccounts, function (obj) { + return obj.id === walletAccountId + }) + await this.refreshWalletAccounts() + } catch (error) { + this.$q.notify({ + type: 'warning', + message: 'Error while deleting wallet account. Please try again.', + timeout: 10000 + }) + } + }) + }, +// ?network=${this.network} + getSilntWallets: async function () { + try { + const {data} = await LNbits.api.request( + 'GET', + `/silnt/api/v1/wallet`, + this.inkey + ) + return data + } catch (error) { + this.$q.notify({ + type: 'warning', + message: 'Failed to fetch wallets.', + timeout: 10000 + }) + LNbits.utils.notifyApiError(error) + } + return [] + }, + refreshWalletAccounts: async function () { + this.walletAccounts = [] + const wallets = await this.getSilntWallets() + this.walletAccounts = wallets.map(w => mapWalletAccount(w)) + // this.$emit('accounts-update', this.walletAccounts) + }, + // getBalanceForWallet: function (walletId) { + // const amount = this.addresses + // .filter(a => a.wallet === walletId) + // .reduce((t, a) => t + a.amount || 0, 0) + // return this.satBtc(amount) + // }, + closeFormDialog: function () { + this.formDialog.data = { + is_unique: false + } + }, + closeUpdateDialog: function () { + this.updateDialog.data = { + is_unique: false + } + }, + getAccountDescription: function (accountType) { + return getAccountDescription(accountType) + }, + openGetFreshAddressDialog: async function (walletId) { + const {data} = await LNbits.api.request( + 'GET', + `/silnt/api/v1/address/${walletId}`, + this.inkey + ) + const addressData = mapAddressesData(data) + + addressData.note = `Shared on ${currentDateTime()}` + const lastActiveAddress = + this.addresses + .filter( + a => a.wallet === addressData.wallet && !a.isChange && a.hasActivity + ) + .pop() || {} + addressData.gapLimitExceeded = + !addressData.isChange && + addressData.addressIndex > + lastActiveAddress.addressIndex + DEFAULT_RECEIVE_GAP_LIMIT + + const wallet = this.walletAccounts.find(w => w.id === walletId) || {} + wallet.address_no = addressData.addressIndex + this.$emit('new-receive-address', {addressData, wallet}) + }, + showAddAccountDialog: function () { + this.formDialog.show = true + }, + showUpdateWalletDialog: function () { + this.updateDialog.show = true + }, + // todo: bad. base.js not present in custom components + copyText: function (text, message, position) { + var notify = this.$q.notify + Quasar.utils.copyToClipboard(text).then(function () { + notify({ + message: message || 'Copied to clipboard!', + position: position || 'bottom' + }) + }) + }, + }, + created: async function () { + if (this.inkey) { + await this.refreshWalletAccounts() + } + } +}) diff --git a/static/conversion-example.png b/static/conversion-example.png deleted file mode 100644 index 544e6335cedf8bc2ac700fd5721a93c69f2fcd91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78613 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 diff --git a/static/conversion-example2.png b/static/conversion-example2.png deleted file mode 100644 index 7543fdc9e9a789ef6b822ae4a4977cb6c5e3cf23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40977 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 KMNUMnLSTZQBRAy$ diff --git a/static/fastapilogo.png b/static/fastapilogo.png deleted file mode 100644 index 57eb6a80055d60ed4db27f48768b5e583524b2ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14237 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. See LICENSE.txt. */ +;(function (root) { + 'use strict' + + function checkInt(value) { + return parseInt(value) === value + } + + function checkInts(arrayish) { + if (!checkInt(arrayish.length)) { + return false + } + + for (var i = 0; i < arrayish.length; i++) { + if (!checkInt(arrayish[i]) || arrayish[i] < 0 || arrayish[i] > 255) { + return false + } + } + + return true + } + + function coerceArray(arg, copy) { + // ArrayBuffer view + if (arg.buffer && arg.name === 'Uint8Array') { + if (copy) { + if (arg.slice) { + arg = arg.slice() + } else { + arg = Array.prototype.slice.call(arg) + } + } + + return arg + } + + // It's an array; check it is a valid representation of a byte + if (Array.isArray(arg)) { + if (!checkInts(arg)) { + throw new Error('Array contains invalid value: ' + arg) + } + + return new Uint8Array(arg) + } + + // Something else, but behaves like an array (maybe a Buffer? Arguments?) + if (checkInt(arg.length) && checkInts(arg)) { + return new Uint8Array(arg) + } + throw new Error('unsupported array-like object') + } + + function createArray(length) { + return new Uint8Array(length) + } + + function copyArray( + sourceArray, + targetArray, + targetStart, + sourceStart, + sourceEnd + ) { + if (sourceStart != null || sourceEnd != null) { + if (sourceArray.slice) { + sourceArray = sourceArray.slice(sourceStart, sourceEnd) + } else { + sourceArray = Array.prototype.slice.call( + sourceArray, + sourceStart, + sourceEnd + ) + } + } + targetArray.set(sourceArray, targetStart) + } + + var convertUtf8 = (function () { + function toBytes(text) { + var result = [], + i = 0 + text = encodeURI(text) + while (i < text.length) { + var c = text.charCodeAt(i++) + + // if it is a % sign, encode the following 2 bytes as a hex value + if (c === 37) { + result.push(parseInt(text.substr(i, 2), 16)) + i += 2 + + // otherwise, just the actual byte + } else { + result.push(c) + } + } + + return coerceArray(result) + } + + function fromBytes(bytes) { + var result = [], + i = 0 + + while (i < bytes.length) { + var c = bytes[i] + + if (c < 128) { + result.push(String.fromCharCode(c)) + i++ + } else if (c > 191 && c < 224) { + result.push( + String.fromCharCode(((c & 0x1f) << 6) | (bytes[i + 1] & 0x3f)) + ) + i += 2 + } else { + result.push( + String.fromCharCode( + ((c & 0x0f) << 12) | + ((bytes[i + 1] & 0x3f) << 6) | + (bytes[i + 2] & 0x3f) + ) + ) + i += 3 + } + } + + return result.join('') + } + + return { + toBytes: toBytes, + fromBytes: fromBytes + } + })() + + var convertHex = (function () { + function toBytes(text) { + var result = [] + for (var i = 0; i < text.length; i += 2) { + result.push(parseInt(text.substr(i, 2), 16)) + } + + return result + } + + // http://ixti.net/development/javascript/2011/11/11/base64-encodedecode-of-utf8-in-browser-with-js.html + var Hex = '0123456789abcdef' + + function fromBytes(bytes) { + var result = [] + for (var i = 0; i < bytes.length; i++) { + var v = bytes[i] + result.push(Hex[(v & 0xf0) >> 4] + Hex[v & 0x0f]) + } + return result.join('') + } + + return { + toBytes: toBytes, + fromBytes: fromBytes + } + })() + + // Number of rounds by keysize + var numberOfRounds = {16: 10, 24: 12, 32: 14} + + // Round constant words + var rcon = [ + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, + 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, + 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 + ] + + // S-box and Inverse S-box (S is for Substitution) + var S = [ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, + 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, + 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, + 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, + 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, + 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, + 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, + 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, + 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, + 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, + 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, + 0xb0, 0x54, 0xbb, 0x16 + ] + var Si = [ + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, + 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, + 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, + 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, + 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, + 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, + 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, + 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, + 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, + 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, + 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, + 0x55, 0x21, 0x0c, 0x7d + ] + + // Transformations for encryption + var T1 = [ + 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, + 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, + 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d, + 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, + 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, + 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, + 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, + 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, + 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, + 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, + 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, 0x1209091b, 0x1d83839e, + 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, + 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, + 0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, + 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46, + 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, + 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, + 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, + 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe, + 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, + 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, + 0xfdf3f30e, 0xbfd2d26d, 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, + 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2, + 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, + 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, + 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, + 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256, + 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, + 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, + 0xd3e4e437, 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, + 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, + 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, + 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, + 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, + 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42, + 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, + 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, + 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, + 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22, + 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, + 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, + 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, + 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a + ] + var T2 = [ + 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b, + 0xb1de6f6f, 0x5491c5c5, 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, + 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, 0x458fcaca, 0x9d1f8282, + 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0, + 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4, + 0x96e47272, 0x5b9bc0c0, 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, + 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc, 0x5c683434, 0xf451a5a5, + 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, + 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696, + 0x0f0a0505, 0xb52f9a9a, 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, + 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, 0x1b120909, 0x9e1d8383, + 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, + 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3, + 0x715e2f2f, 0x97138484, 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, + 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, 0xbed46a6a, 0x468dcbcb, + 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, + 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d, + 0x55663333, 0x94118585, 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, + 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, 0xf3a25151, 0xfe5da3a3, + 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5, + 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff, + 0x0efdf3f3, 0x6dbfd2d2, 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, + 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, 0x5793c4c4, 0xf255a7a7, + 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, + 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a, + 0xab3b9090, 0x830b8888, 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, + 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, 0x3bdbe0e0, 0x56643232, + 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c, + 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595, + 0x37d3e4e4, 0x8bf27979, 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, + 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, 0xb4d86c6c, 0xfaac5656, + 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, + 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6, + 0xc773b4b4, 0x5197c6c6, 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, + 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, 0x90e07070, 0x427c3e3e, + 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e, + 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1, + 0x273a1d1d, 0xb9279e9e, 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, + 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, 0xb62d9b9b, 0x223c1e1e, + 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, + 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6, + 0xc6844242, 0xb8d06868, 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, + 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616 + ] + var T3 = [ + 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b, + 0x6fb1de6f, 0xc55491c5, 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, + 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, 0xca458fca, 0x829d1f82, + 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, + 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4, + 0x7296e472, 0xc05b9bc0, 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, + 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, 0x345c6834, 0xa5f451a5, + 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, + 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796, + 0x050f0a05, 0x9ab52f9a, 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, + 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, 0x091b1209, 0x839e1d83, + 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, + 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3, + 0x2f715e2f, 0x84971384, 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, + 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, 0x6abed46a, 0xcb468dcb, + 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, + 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d, + 0x33556633, 0x85941185, 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, + 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, 0x51f3a251, 0xa3fe5da3, + 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, + 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff, + 0xf30efdf3, 0xd26dbfd2, 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, + 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, 0xc45793c4, 0xa7f255a7, + 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, + 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a, + 0x90ab3b90, 0x88830b88, 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, + 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb, 0xe03bdbe0, 0x32566432, + 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c, + 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195, + 0xe437d3e4, 0x798bf279, 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, + 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, 0x6cb4d86c, 0x56faac56, + 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008, + 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6, + 0xb4c773b4, 0xc65197c6, 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, + 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, 0x7090e070, 0x3e427c3e, + 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e, + 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1, + 0x1d273a1d, 0x9eb9279e, 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, + 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, 0x9bb62d9b, 0x1e223c1e, + 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, + 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6, + 0x42c68442, 0x68b8d068, 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, + 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16 + ] + var T4 = [ + 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6, + 0x6f6fb1de, 0xc5c55491, 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, + 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, 0xcaca458f, 0x82829d1f, + 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, + 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753, + 0x727296e4, 0xc0c05b9b, 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, + 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, 0x34345c68, 0xa5a5f451, + 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, + 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137, + 0x05050f0a, 0x9a9ab52f, 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, + 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, 0x09091b12, 0x83839e1d, + 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, + 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd, + 0x2f2f715e, 0x84849713, 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, + 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, 0x6a6abed4, 0xcbcb468d, + 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, + 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a, + 0x33335566, 0x85859411, 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, + 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, 0x5151f3a2, 0xa3a3fe5d, + 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, + 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5, + 0xf3f30efd, 0xd2d26dbf, 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, + 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, 0xc4c45793, 0xa7a7f255, + 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, + 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54, + 0x9090ab3b, 0x8888830b, 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, + 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad, 0xe0e03bdb, 0x32325664, + 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8, + 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431, + 0xe4e437d3, 0x79798bf2, 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, + 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, 0x6c6cb4d8, 0x5656faac, + 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810, + 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157, + 0xb4b4c773, 0xc6c65197, 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, + 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, 0x707090e0, 0x3e3e427c, + 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c, + 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899, + 0x1d1d273a, 0x9e9eb927, 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, + 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, 0x9b9bb62d, 0x1e1e223c, + 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, + 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7, + 0x4242c684, 0x6868b8d0, 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, + 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c + ] + + // Transformations for decryption + var T5 = [ + 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, + 0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, + 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, 0xdeb15a49, 0x25ba1b67, + 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, + 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, + 0x49e06929, 0x8ec9c844, 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, + 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182, + 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, + 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, + 0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, + 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, 0x8acf1c2b, 0xa779b492, + 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, + 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, + 0x5e719f06, 0xbd6e1051, 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, + 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997, + 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, + 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, + 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, + 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, 0x0c0a67b1, 0x9357e70f, + 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, + 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, + 0x2db6a8b9, 0x141ea9c8, 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, + 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc, + 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, + 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, + 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, + 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, 0x87494ec7, 0xd938d1c1, + 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, + 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, + 0x2e39f75e, 0x82c3aff5, 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, + 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4, + 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, + 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, + 0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, + 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, 0x764dd68d, 0x43efb04d, + 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, + 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, + 0xe9105633, 0x6dd64713, 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, + 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f, + 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, + 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, + 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, + 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742 + ] + var T6 = [ + 0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 0xcb3bab6b, 0xf11f9d45, + 0xabacfa58, 0x934be303, 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, + 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, 0x49deb15a, 0x6725ba1b, + 0x9845ea0e, 0xe15dfec0, 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, + 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 0x2dd4be83, 0xd3587421, + 0x2949e069, 0x448ec9c8, 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, + 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, 0x1863df4a, 0x82e51a31, + 0x60975133, 0x4562537f, 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, + 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 0x23ab73d3, 0xe2724b02, + 0x57e31f8f, 0x2a6655ab, 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, + 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, 0x2b8acf1c, 0x92a779b4, + 0xf0f307f2, 0xa14e69e2, 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, + 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 0x390b83ec, 0xaa4060ef, + 0x065e719f, 0x51bd6e10, 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, + 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015, 0x241998fb, 0x97d6bde9, + 0xcc894043, 0x7767d99e, 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, + 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, 0x83098086, 0x48322bed, + 0xac1e1170, 0x4e6c5a72, 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, + 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, 0xb10c0a67, 0x0f9357e7, + 0xd2b4ee96, 0x9e1b9b91, 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, + 0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 0x0b0e090d, 0xadf28bc7, + 0xb92db6a8, 0xc8141ea9, 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, + 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, 0x768b4329, 0xdccb23c6, + 0x68b6edfc, 0x63b8e4f1, 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, + 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 0x4b1d9e2f, 0xf3dcb230, + 0xec0d8652, 0xd077c1e3, 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, + 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, 0xc787494e, 0xc1d938d1, + 0xfe8ccaa2, 0x3698d40b, 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, + 0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, 0xc2f68d13, 0xe890d8b8, + 0x5e2e39f7, 0xf582c3af, 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, + 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, 0x09cd2678, 0xf46e5918, + 0x01ec9ab7, 0xa8834f9a, 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8, + 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 0xaf31a4b2, 0x312a3f23, + 0x30c6a594, 0xc035a266, 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, + 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6, 0x8d764dd6, 0x4d43efb0, + 0x54ccaa4d, 0xdfe49604, 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, + 0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 0x5ab3671d, 0x5292dbd2, + 0x33e91056, 0x136dd647, 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, + 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, 0x599cd2df, 0x3f55f273, + 0x791814ce, 0xbf73c737, 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, + 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 0x72161dc3, 0x0cbce225, + 0x8b283c49, 0x41ff0d95, 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, + 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857 + ] + var T7 = [ + 0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 0x6bcb3bab, 0x45f11f9d, + 0x58abacfa, 0x03934be3, 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, + 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, 0x5a49deb1, 0x1b6725ba, + 0x0e9845ea, 0xc0e15dfe, 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, + 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 0x832dd4be, 0x21d35874, + 0x692949e0, 0xc8448ec9, 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, + 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, 0x4a1863df, 0x3182e51a, + 0x33609751, 0x7f456253, 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, + 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 0xd323ab73, 0x02e2724b, + 0x8f57e31f, 0xab2a6655, 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, + 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, 0x1c2b8acf, 0xb492a779, + 0xf2f0f307, 0xe2a14e69, 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, + 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 0xec390b83, 0xefaa4060, + 0x9f065e71, 0x1051bd6e, 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, + 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, 0xfb241998, 0xe997d6bd, + 0x43cc8940, 0x9e7767d9, 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, + 0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, 0x86830980, 0xed48322b, + 0x70ac1e11, 0x724e6c5a, 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, + 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, 0x67b10c0a, 0xe70f9357, + 0x96d2b4ee, 0x919e1b9b, 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, + 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 0x0d0b0e09, 0xc7adf28b, + 0xa8b92db6, 0xa9c8141e, 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, + 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, 0x29768b43, 0xc6dccb23, + 0xfc68b6ed, 0xf163b8e4, 0xdccad731, 0x85104263, 0x22401397, 0x112084c6, + 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 0x2f4b1d9e, 0x30f3dcb2, + 0x52ec0d86, 0xe3d077c1, 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, + 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, 0x4ec78749, 0xd1c1d938, + 0xa2fe8cca, 0x0b3698d4, 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, + 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 0x13c2f68d, 0xb8e890d8, + 0xf75e2e39, 0xaff582c3, 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, + 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, 0x7809cd26, 0x18f46e59, + 0xb701ec9a, 0x9aa8834f, 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, + 0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, 0xb2af31a4, 0x23312a3f, + 0x9430c6a5, 0x66c035a2, 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, + 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, 0xd68d764d, 0xb04d43ef, + 0x4d54ccaa, 0x04dfe496, 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, + 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 0x1d5ab367, 0xd25292db, + 0x5633e910, 0x47136dd6, 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, + 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, 0xdf599cd2, 0x733f55f2, + 0xce791814, 0x37bf73c7, 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, + 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 0xc372161d, 0x250cbce2, + 0x498b283c, 0x9541ff0d, 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, + 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8 + ] + var T8 = [ + 0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f, + 0xfa58abac, 0xe303934b, 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, + 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, 0xb15a49de, 0xba1b6725, + 0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, + 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358, + 0xe0692949, 0xc9c8448e, 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, + 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, 0xdf4a1863, 0x1a3182e5, + 0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9, + 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272, + 0x1f8f57e3, 0x55ab2a66, 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, + 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced, 0xcf1c2b8a, 0x79b492a7, + 0x07f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4, + 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40, + 0x719f065e, 0x6e1051bd, 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, + 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60, 0x98fb2419, 0xbde997d6, + 0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, + 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, 0x80868309, 0x2bed4832, + 0x1170ac1e, 0x5a724e6c, 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, + 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, 0x0a67b10c, 0x57e70f93, + 0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, + 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x090d0b0e, 0x8bc7adf2, + 0xb6a8b92d, 0x1ea9c814, 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, + 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, 0x4329768b, 0x23c6dccb, + 0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, + 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc, + 0x8652ec0d, 0xc1e3d077, 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, + 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, 0x494ec787, 0x38d1c1d9, + 0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, + 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890, + 0x39f75e2e, 0xc3aff582, 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, + 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, 0x267809cd, 0x5918f46e, + 0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, + 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a, + 0xa59430c6, 0xa266c035, 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, + 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, 0x4dd68d76, 0xefb04d43, + 0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, + 0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, 0x671d5ab3, 0xdbd25292, + 0x105633e9, 0xd647136d, 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, + 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, 0xd2df599c, 0xf2733f55, + 0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, + 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc, + 0x3c498b28, 0x0d9541ff, 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, + 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0 + ] + + // Transformations for decryption key expansion + var U1 = [ + 0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, + 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, + 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, + 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, + 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, + 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, + 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, + 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, + 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, + 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, + 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, + 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, + 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, + 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, + 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, + 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, + 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, + 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, + 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, + 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, + 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, + 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, + 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, + 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, + 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, + 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, + 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, + 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, + 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, + 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, + 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, + 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, + 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, + 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, + 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, + 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, + 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, + 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, + 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, + 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, + 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, + 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, + 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3 + ] + var U2 = [ + 0x00000000, 0x0b0e090d, 0x161c121a, 0x1d121b17, 0x2c382434, 0x27362d39, + 0x3a24362e, 0x312a3f23, 0x58704868, 0x537e4165, 0x4e6c5a72, 0x4562537f, + 0x74486c5c, 0x7f466551, 0x62547e46, 0x695a774b, 0xb0e090d0, 0xbbee99dd, + 0xa6fc82ca, 0xadf28bc7, 0x9cd8b4e4, 0x97d6bde9, 0x8ac4a6fe, 0x81caaff3, + 0xe890d8b8, 0xe39ed1b5, 0xfe8ccaa2, 0xf582c3af, 0xc4a8fc8c, 0xcfa6f581, + 0xd2b4ee96, 0xd9bae79b, 0x7bdb3bbb, 0x70d532b6, 0x6dc729a1, 0x66c920ac, + 0x57e31f8f, 0x5ced1682, 0x41ff0d95, 0x4af10498, 0x23ab73d3, 0x28a57ade, + 0x35b761c9, 0x3eb968c4, 0x0f9357e7, 0x049d5eea, 0x198f45fd, 0x12814cf0, + 0xcb3bab6b, 0xc035a266, 0xdd27b971, 0xd629b07c, 0xe7038f5f, 0xec0d8652, + 0xf11f9d45, 0xfa119448, 0x934be303, 0x9845ea0e, 0x8557f119, 0x8e59f814, + 0xbf73c737, 0xb47dce3a, 0xa96fd52d, 0xa261dc20, 0xf6ad766d, 0xfda37f60, + 0xe0b16477, 0xebbf6d7a, 0xda955259, 0xd19b5b54, 0xcc894043, 0xc787494e, + 0xaedd3e05, 0xa5d33708, 0xb8c12c1f, 0xb3cf2512, 0x82e51a31, 0x89eb133c, + 0x94f9082b, 0x9ff70126, 0x464de6bd, 0x4d43efb0, 0x5051f4a7, 0x5b5ffdaa, + 0x6a75c289, 0x617bcb84, 0x7c69d093, 0x7767d99e, 0x1e3daed5, 0x1533a7d8, + 0x0821bccf, 0x032fb5c2, 0x32058ae1, 0x390b83ec, 0x241998fb, 0x2f1791f6, + 0x8d764dd6, 0x867844db, 0x9b6a5fcc, 0x906456c1, 0xa14e69e2, 0xaa4060ef, + 0xb7527bf8, 0xbc5c72f5, 0xd50605be, 0xde080cb3, 0xc31a17a4, 0xc8141ea9, + 0xf93e218a, 0xf2302887, 0xef223390, 0xe42c3a9d, 0x3d96dd06, 0x3698d40b, + 0x2b8acf1c, 0x2084c611, 0x11aef932, 0x1aa0f03f, 0x07b2eb28, 0x0cbce225, + 0x65e6956e, 0x6ee89c63, 0x73fa8774, 0x78f48e79, 0x49deb15a, 0x42d0b857, + 0x5fc2a340, 0x54ccaa4d, 0xf741ecda, 0xfc4fe5d7, 0xe15dfec0, 0xea53f7cd, + 0xdb79c8ee, 0xd077c1e3, 0xcd65daf4, 0xc66bd3f9, 0xaf31a4b2, 0xa43fadbf, + 0xb92db6a8, 0xb223bfa5, 0x83098086, 0x8807898b, 0x9515929c, 0x9e1b9b91, + 0x47a17c0a, 0x4caf7507, 0x51bd6e10, 0x5ab3671d, 0x6b99583e, 0x60975133, + 0x7d854a24, 0x768b4329, 0x1fd13462, 0x14df3d6f, 0x09cd2678, 0x02c32f75, + 0x33e91056, 0x38e7195b, 0x25f5024c, 0x2efb0b41, 0x8c9ad761, 0x8794de6c, + 0x9a86c57b, 0x9188cc76, 0xa0a2f355, 0xabacfa58, 0xb6bee14f, 0xbdb0e842, + 0xd4ea9f09, 0xdfe49604, 0xc2f68d13, 0xc9f8841e, 0xf8d2bb3d, 0xf3dcb230, + 0xeecea927, 0xe5c0a02a, 0x3c7a47b1, 0x37744ebc, 0x2a6655ab, 0x21685ca6, + 0x10426385, 0x1b4c6a88, 0x065e719f, 0x0d507892, 0x640a0fd9, 0x6f0406d4, + 0x72161dc3, 0x791814ce, 0x48322bed, 0x433c22e0, 0x5e2e39f7, 0x552030fa, + 0x01ec9ab7, 0x0ae293ba, 0x17f088ad, 0x1cfe81a0, 0x2dd4be83, 0x26dab78e, + 0x3bc8ac99, 0x30c6a594, 0x599cd2df, 0x5292dbd2, 0x4f80c0c5, 0x448ec9c8, + 0x75a4f6eb, 0x7eaaffe6, 0x63b8e4f1, 0x68b6edfc, 0xb10c0a67, 0xba02036a, + 0xa710187d, 0xac1e1170, 0x9d342e53, 0x963a275e, 0x8b283c49, 0x80263544, + 0xe97c420f, 0xe2724b02, 0xff605015, 0xf46e5918, 0xc544663b, 0xce4a6f36, + 0xd3587421, 0xd8567d2c, 0x7a37a10c, 0x7139a801, 0x6c2bb316, 0x6725ba1b, + 0x560f8538, 0x5d018c35, 0x40139722, 0x4b1d9e2f, 0x2247e964, 0x2949e069, + 0x345bfb7e, 0x3f55f273, 0x0e7fcd50, 0x0571c45d, 0x1863df4a, 0x136dd647, + 0xcad731dc, 0xc1d938d1, 0xdccb23c6, 0xd7c52acb, 0xe6ef15e8, 0xede11ce5, + 0xf0f307f2, 0xfbfd0eff, 0x92a779b4, 0x99a970b9, 0x84bb6bae, 0x8fb562a3, + 0xbe9f5d80, 0xb591548d, 0xa8834f9a, 0xa38d4697 + ] + var U3 = [ + 0x00000000, 0x0d0b0e09, 0x1a161c12, 0x171d121b, 0x342c3824, 0x3927362d, + 0x2e3a2436, 0x23312a3f, 0x68587048, 0x65537e41, 0x724e6c5a, 0x7f456253, + 0x5c74486c, 0x517f4665, 0x4662547e, 0x4b695a77, 0xd0b0e090, 0xddbbee99, + 0xcaa6fc82, 0xc7adf28b, 0xe49cd8b4, 0xe997d6bd, 0xfe8ac4a6, 0xf381caaf, + 0xb8e890d8, 0xb5e39ed1, 0xa2fe8cca, 0xaff582c3, 0x8cc4a8fc, 0x81cfa6f5, + 0x96d2b4ee, 0x9bd9bae7, 0xbb7bdb3b, 0xb670d532, 0xa16dc729, 0xac66c920, + 0x8f57e31f, 0x825ced16, 0x9541ff0d, 0x984af104, 0xd323ab73, 0xde28a57a, + 0xc935b761, 0xc43eb968, 0xe70f9357, 0xea049d5e, 0xfd198f45, 0xf012814c, + 0x6bcb3bab, 0x66c035a2, 0x71dd27b9, 0x7cd629b0, 0x5fe7038f, 0x52ec0d86, + 0x45f11f9d, 0x48fa1194, 0x03934be3, 0x0e9845ea, 0x198557f1, 0x148e59f8, + 0x37bf73c7, 0x3ab47dce, 0x2da96fd5, 0x20a261dc, 0x6df6ad76, 0x60fda37f, + 0x77e0b164, 0x7aebbf6d, 0x59da9552, 0x54d19b5b, 0x43cc8940, 0x4ec78749, + 0x05aedd3e, 0x08a5d337, 0x1fb8c12c, 0x12b3cf25, 0x3182e51a, 0x3c89eb13, + 0x2b94f908, 0x269ff701, 0xbd464de6, 0xb04d43ef, 0xa75051f4, 0xaa5b5ffd, + 0x896a75c2, 0x84617bcb, 0x937c69d0, 0x9e7767d9, 0xd51e3dae, 0xd81533a7, + 0xcf0821bc, 0xc2032fb5, 0xe132058a, 0xec390b83, 0xfb241998, 0xf62f1791, + 0xd68d764d, 0xdb867844, 0xcc9b6a5f, 0xc1906456, 0xe2a14e69, 0xefaa4060, + 0xf8b7527b, 0xf5bc5c72, 0xbed50605, 0xb3de080c, 0xa4c31a17, 0xa9c8141e, + 0x8af93e21, 0x87f23028, 0x90ef2233, 0x9de42c3a, 0x063d96dd, 0x0b3698d4, + 0x1c2b8acf, 0x112084c6, 0x3211aef9, 0x3f1aa0f0, 0x2807b2eb, 0x250cbce2, + 0x6e65e695, 0x636ee89c, 0x7473fa87, 0x7978f48e, 0x5a49deb1, 0x5742d0b8, + 0x405fc2a3, 0x4d54ccaa, 0xdaf741ec, 0xd7fc4fe5, 0xc0e15dfe, 0xcdea53f7, + 0xeedb79c8, 0xe3d077c1, 0xf4cd65da, 0xf9c66bd3, 0xb2af31a4, 0xbfa43fad, + 0xa8b92db6, 0xa5b223bf, 0x86830980, 0x8b880789, 0x9c951592, 0x919e1b9b, + 0x0a47a17c, 0x074caf75, 0x1051bd6e, 0x1d5ab367, 0x3e6b9958, 0x33609751, + 0x247d854a, 0x29768b43, 0x621fd134, 0x6f14df3d, 0x7809cd26, 0x7502c32f, + 0x5633e910, 0x5b38e719, 0x4c25f502, 0x412efb0b, 0x618c9ad7, 0x6c8794de, + 0x7b9a86c5, 0x769188cc, 0x55a0a2f3, 0x58abacfa, 0x4fb6bee1, 0x42bdb0e8, + 0x09d4ea9f, 0x04dfe496, 0x13c2f68d, 0x1ec9f884, 0x3df8d2bb, 0x30f3dcb2, + 0x27eecea9, 0x2ae5c0a0, 0xb13c7a47, 0xbc37744e, 0xab2a6655, 0xa621685c, + 0x85104263, 0x881b4c6a, 0x9f065e71, 0x920d5078, 0xd9640a0f, 0xd46f0406, + 0xc372161d, 0xce791814, 0xed48322b, 0xe0433c22, 0xf75e2e39, 0xfa552030, + 0xb701ec9a, 0xba0ae293, 0xad17f088, 0xa01cfe81, 0x832dd4be, 0x8e26dab7, + 0x993bc8ac, 0x9430c6a5, 0xdf599cd2, 0xd25292db, 0xc54f80c0, 0xc8448ec9, + 0xeb75a4f6, 0xe67eaaff, 0xf163b8e4, 0xfc68b6ed, 0x67b10c0a, 0x6aba0203, + 0x7da71018, 0x70ac1e11, 0x539d342e, 0x5e963a27, 0x498b283c, 0x44802635, + 0x0fe97c42, 0x02e2724b, 0x15ff6050, 0x18f46e59, 0x3bc54466, 0x36ce4a6f, + 0x21d35874, 0x2cd8567d, 0x0c7a37a1, 0x017139a8, 0x166c2bb3, 0x1b6725ba, + 0x38560f85, 0x355d018c, 0x22401397, 0x2f4b1d9e, 0x642247e9, 0x692949e0, + 0x7e345bfb, 0x733f55f2, 0x500e7fcd, 0x5d0571c4, 0x4a1863df, 0x47136dd6, + 0xdccad731, 0xd1c1d938, 0xc6dccb23, 0xcbd7c52a, 0xe8e6ef15, 0xe5ede11c, + 0xf2f0f307, 0xfffbfd0e, 0xb492a779, 0xb999a970, 0xae84bb6b, 0xa38fb562, + 0x80be9f5d, 0x8db59154, 0x9aa8834f, 0x97a38d46 + ] + var U4 = [ + 0x00000000, 0x090d0b0e, 0x121a161c, 0x1b171d12, 0x24342c38, 0x2d392736, + 0x362e3a24, 0x3f23312a, 0x48685870, 0x4165537e, 0x5a724e6c, 0x537f4562, + 0x6c5c7448, 0x65517f46, 0x7e466254, 0x774b695a, 0x90d0b0e0, 0x99ddbbee, + 0x82caa6fc, 0x8bc7adf2, 0xb4e49cd8, 0xbde997d6, 0xa6fe8ac4, 0xaff381ca, + 0xd8b8e890, 0xd1b5e39e, 0xcaa2fe8c, 0xc3aff582, 0xfc8cc4a8, 0xf581cfa6, + 0xee96d2b4, 0xe79bd9ba, 0x3bbb7bdb, 0x32b670d5, 0x29a16dc7, 0x20ac66c9, + 0x1f8f57e3, 0x16825ced, 0x0d9541ff, 0x04984af1, 0x73d323ab, 0x7ade28a5, + 0x61c935b7, 0x68c43eb9, 0x57e70f93, 0x5eea049d, 0x45fd198f, 0x4cf01281, + 0xab6bcb3b, 0xa266c035, 0xb971dd27, 0xb07cd629, 0x8f5fe703, 0x8652ec0d, + 0x9d45f11f, 0x9448fa11, 0xe303934b, 0xea0e9845, 0xf1198557, 0xf8148e59, + 0xc737bf73, 0xce3ab47d, 0xd52da96f, 0xdc20a261, 0x766df6ad, 0x7f60fda3, + 0x6477e0b1, 0x6d7aebbf, 0x5259da95, 0x5b54d19b, 0x4043cc89, 0x494ec787, + 0x3e05aedd, 0x3708a5d3, 0x2c1fb8c1, 0x2512b3cf, 0x1a3182e5, 0x133c89eb, + 0x082b94f9, 0x01269ff7, 0xe6bd464d, 0xefb04d43, 0xf4a75051, 0xfdaa5b5f, + 0xc2896a75, 0xcb84617b, 0xd0937c69, 0xd99e7767, 0xaed51e3d, 0xa7d81533, + 0xbccf0821, 0xb5c2032f, 0x8ae13205, 0x83ec390b, 0x98fb2419, 0x91f62f17, + 0x4dd68d76, 0x44db8678, 0x5fcc9b6a, 0x56c19064, 0x69e2a14e, 0x60efaa40, + 0x7bf8b752, 0x72f5bc5c, 0x05bed506, 0x0cb3de08, 0x17a4c31a, 0x1ea9c814, + 0x218af93e, 0x2887f230, 0x3390ef22, 0x3a9de42c, 0xdd063d96, 0xd40b3698, + 0xcf1c2b8a, 0xc6112084, 0xf93211ae, 0xf03f1aa0, 0xeb2807b2, 0xe2250cbc, + 0x956e65e6, 0x9c636ee8, 0x877473fa, 0x8e7978f4, 0xb15a49de, 0xb85742d0, + 0xa3405fc2, 0xaa4d54cc, 0xecdaf741, 0xe5d7fc4f, 0xfec0e15d, 0xf7cdea53, + 0xc8eedb79, 0xc1e3d077, 0xdaf4cd65, 0xd3f9c66b, 0xa4b2af31, 0xadbfa43f, + 0xb6a8b92d, 0xbfa5b223, 0x80868309, 0x898b8807, 0x929c9515, 0x9b919e1b, + 0x7c0a47a1, 0x75074caf, 0x6e1051bd, 0x671d5ab3, 0x583e6b99, 0x51336097, + 0x4a247d85, 0x4329768b, 0x34621fd1, 0x3d6f14df, 0x267809cd, 0x2f7502c3, + 0x105633e9, 0x195b38e7, 0x024c25f5, 0x0b412efb, 0xd7618c9a, 0xde6c8794, + 0xc57b9a86, 0xcc769188, 0xf355a0a2, 0xfa58abac, 0xe14fb6be, 0xe842bdb0, + 0x9f09d4ea, 0x9604dfe4, 0x8d13c2f6, 0x841ec9f8, 0xbb3df8d2, 0xb230f3dc, + 0xa927eece, 0xa02ae5c0, 0x47b13c7a, 0x4ebc3774, 0x55ab2a66, 0x5ca62168, + 0x63851042, 0x6a881b4c, 0x719f065e, 0x78920d50, 0x0fd9640a, 0x06d46f04, + 0x1dc37216, 0x14ce7918, 0x2bed4832, 0x22e0433c, 0x39f75e2e, 0x30fa5520, + 0x9ab701ec, 0x93ba0ae2, 0x88ad17f0, 0x81a01cfe, 0xbe832dd4, 0xb78e26da, + 0xac993bc8, 0xa59430c6, 0xd2df599c, 0xdbd25292, 0xc0c54f80, 0xc9c8448e, + 0xf6eb75a4, 0xffe67eaa, 0xe4f163b8, 0xedfc68b6, 0x0a67b10c, 0x036aba02, + 0x187da710, 0x1170ac1e, 0x2e539d34, 0x275e963a, 0x3c498b28, 0x35448026, + 0x420fe97c, 0x4b02e272, 0x5015ff60, 0x5918f46e, 0x663bc544, 0x6f36ce4a, + 0x7421d358, 0x7d2cd856, 0xa10c7a37, 0xa8017139, 0xb3166c2b, 0xba1b6725, + 0x8538560f, 0x8c355d01, 0x97224013, 0x9e2f4b1d, 0xe9642247, 0xe0692949, + 0xfb7e345b, 0xf2733f55, 0xcd500e7f, 0xc45d0571, 0xdf4a1863, 0xd647136d, + 0x31dccad7, 0x38d1c1d9, 0x23c6dccb, 0x2acbd7c5, 0x15e8e6ef, 0x1ce5ede1, + 0x07f2f0f3, 0x0efffbfd, 0x79b492a7, 0x70b999a9, 0x6bae84bb, 0x62a38fb5, + 0x5d80be9f, 0x548db591, 0x4f9aa883, 0x4697a38d + ] + + function convertToInt32(bytes) { + var result = [] + for (var i = 0; i < bytes.length; i += 4) { + result.push( + (bytes[i] << 24) | + (bytes[i + 1] << 16) | + (bytes[i + 2] << 8) | + bytes[i + 3] + ) + } + return result + } + + var AES = function (key) { + if (!(this instanceof AES)) { + throw Error('AES must be instanitated with `new`') + } + + Object.defineProperty(this, 'key', { + value: coerceArray(key, true) + }) + + this._prepare() + } + + AES.prototype._prepare = function () { + var rounds = numberOfRounds[this.key.length] + if (rounds == null) { + throw new Error('invalid key size (must be 16, 24 or 32 bytes)') + } + + // encryption round keys + this._Ke = [] + + // decryption round keys + this._Kd = [] + + for (var i = 0; i <= rounds; i++) { + this._Ke.push([0, 0, 0, 0]) + this._Kd.push([0, 0, 0, 0]) + } + + var roundKeyCount = (rounds + 1) * 4 + var KC = this.key.length / 4 + + // convert the key into ints + var tk = convertToInt32(this.key) + + // copy values into round key arrays + var index + for (var i = 0; i < KC; i++) { + index = i >> 2 + this._Ke[index][i % 4] = tk[i] + this._Kd[rounds - index][i % 4] = tk[i] + } + + // key expansion (fips-197 section 5.2) + var rconpointer = 0 + var t = KC, + tt + while (t < roundKeyCount) { + tt = tk[KC - 1] + tk[0] ^= + (S[(tt >> 16) & 0xff] << 24) ^ + (S[(tt >> 8) & 0xff] << 16) ^ + (S[tt & 0xff] << 8) ^ + S[(tt >> 24) & 0xff] ^ + (rcon[rconpointer] << 24) + rconpointer += 1 + + // key expansion (for non-256 bit) + if (KC != 8) { + for (var i = 1; i < KC; i++) { + tk[i] ^= tk[i - 1] + } + + // key expansion for 256-bit keys is "slightly different" (fips-197) + } else { + for (var i = 1; i < KC / 2; i++) { + tk[i] ^= tk[i - 1] + } + tt = tk[KC / 2 - 1] + + tk[KC / 2] ^= + S[tt & 0xff] ^ + (S[(tt >> 8) & 0xff] << 8) ^ + (S[(tt >> 16) & 0xff] << 16) ^ + (S[(tt >> 24) & 0xff] << 24) + + for (var i = KC / 2 + 1; i < KC; i++) { + tk[i] ^= tk[i - 1] + } + } + + // copy values into round key arrays + var i = 0, + r, + c + while (i < KC && t < roundKeyCount) { + r = t >> 2 + c = t % 4 + this._Ke[r][c] = tk[i] + this._Kd[rounds - r][c] = tk[i++] + t++ + } + } + + // inverse-cipher-ify the decryption round key (fips-197 section 5.3) + for (var r = 1; r < rounds; r++) { + for (var c = 0; c < 4; c++) { + tt = this._Kd[r][c] + this._Kd[r][c] = + U1[(tt >> 24) & 0xff] ^ + U2[(tt >> 16) & 0xff] ^ + U3[(tt >> 8) & 0xff] ^ + U4[tt & 0xff] + } + } + } + + AES.prototype.encrypt = function (plaintext) { + if (plaintext.length != 16) { + throw new Error('invalid plaintext size (must be 16 bytes)') + } + + var rounds = this._Ke.length - 1 + var a = [0, 0, 0, 0] + + // convert plaintext to (ints ^ key) + var t = convertToInt32(plaintext) + for (var i = 0; i < 4; i++) { + t[i] ^= this._Ke[0][i] + } + + // apply round transforms + for (var r = 1; r < rounds; r++) { + for (var i = 0; i < 4; i++) { + a[i] = + T1[(t[i] >> 24) & 0xff] ^ + T2[(t[(i + 1) % 4] >> 16) & 0xff] ^ + T3[(t[(i + 2) % 4] >> 8) & 0xff] ^ + T4[t[(i + 3) % 4] & 0xff] ^ + this._Ke[r][i] + } + t = a.slice() + } + + // the last round is special + var result = createArray(16), + tt + for (var i = 0; i < 4; i++) { + tt = this._Ke[rounds][i] + result[4 * i] = (S[(t[i] >> 24) & 0xff] ^ (tt >> 24)) & 0xff + result[4 * i + 1] = (S[(t[(i + 1) % 4] >> 16) & 0xff] ^ (tt >> 16)) & 0xff + result[4 * i + 2] = (S[(t[(i + 2) % 4] >> 8) & 0xff] ^ (tt >> 8)) & 0xff + result[4 * i + 3] = (S[t[(i + 3) % 4] & 0xff] ^ tt) & 0xff + } + + return result + } + + AES.prototype.decrypt = function (ciphertext) { + if (ciphertext.length != 16) { + throw new Error('invalid ciphertext size (must be 16 bytes)') + } + + var rounds = this._Kd.length - 1 + var a = [0, 0, 0, 0] + + // convert plaintext to (ints ^ key) + var t = convertToInt32(ciphertext) + for (var i = 0; i < 4; i++) { + t[i] ^= this._Kd[0][i] + } + + // apply round transforms + for (var r = 1; r < rounds; r++) { + for (var i = 0; i < 4; i++) { + a[i] = + T5[(t[i] >> 24) & 0xff] ^ + T6[(t[(i + 3) % 4] >> 16) & 0xff] ^ + T7[(t[(i + 2) % 4] >> 8) & 0xff] ^ + T8[t[(i + 1) % 4] & 0xff] ^ + this._Kd[r][i] + } + t = a.slice() + } + + // the last round is special + var result = createArray(16), + tt + for (var i = 0; i < 4; i++) { + tt = this._Kd[rounds][i] + result[4 * i] = (Si[(t[i] >> 24) & 0xff] ^ (tt >> 24)) & 0xff + result[4 * i + 1] = + (Si[(t[(i + 3) % 4] >> 16) & 0xff] ^ (tt >> 16)) & 0xff + result[4 * i + 2] = (Si[(t[(i + 2) % 4] >> 8) & 0xff] ^ (tt >> 8)) & 0xff + result[4 * i + 3] = (Si[t[(i + 1) % 4] & 0xff] ^ tt) & 0xff + } + + return result + } + + /** + * Mode Of Operation - Electonic Codebook (ECB) + */ + var ModeOfOperationECB = function (key) { + if (!(this instanceof ModeOfOperationECB)) { + throw Error('AES must be instanitated with `new`') + } + + this.description = 'Electronic Code Block' + this.name = 'ecb' + + this._aes = new AES(key) + } + + ModeOfOperationECB.prototype.encrypt = function (plaintext) { + plaintext = coerceArray(plaintext) + + if (plaintext.length % 16 !== 0) { + throw new Error('invalid plaintext size (must be multiple of 16 bytes)') + } + + var ciphertext = createArray(plaintext.length) + var block = createArray(16) + + for (var i = 0; i < plaintext.length; i += 16) { + copyArray(plaintext, block, 0, i, i + 16) + block = this._aes.encrypt(block) + copyArray(block, ciphertext, i) + } + + return ciphertext + } + + ModeOfOperationECB.prototype.decrypt = function (ciphertext) { + ciphertext = coerceArray(ciphertext) + + if (ciphertext.length % 16 !== 0) { + throw new Error('invalid ciphertext size (must be multiple of 16 bytes)') + } + + var plaintext = createArray(ciphertext.length) + var block = createArray(16) + + for (var i = 0; i < ciphertext.length; i += 16) { + copyArray(ciphertext, block, 0, i, i + 16) + block = this._aes.decrypt(block) + copyArray(block, plaintext, i) + } + + return plaintext + } + + /** + * Mode Of Operation - Cipher Block Chaining (CBC) + */ + var ModeOfOperationCBC = function (key, iv) { + if (!(this instanceof ModeOfOperationCBC)) { + throw Error('AES must be instanitated with `new`') + } + + this.description = 'Cipher Block Chaining' + this.name = 'cbc' + + if (!iv) { + iv = createArray(16) + } else if (iv.length != 16) { + throw new Error('invalid initialation vector size (must be 16 bytes)') + } + + this._lastCipherblock = coerceArray(iv, true) + + this._aes = new AES(key) + } + + ModeOfOperationCBC.prototype.encrypt = function (plaintext) { + plaintext = coerceArray(plaintext) + + if (plaintext.length % 16 !== 0) { + throw new Error('invalid plaintext size (must be multiple of 16 bytes)') + } + + var ciphertext = createArray(plaintext.length) + var block = createArray(16) + + for (var i = 0; i < plaintext.length; i += 16) { + copyArray(plaintext, block, 0, i, i + 16) + + for (var j = 0; j < 16; j++) { + block[j] ^= this._lastCipherblock[j] + } + + this._lastCipherblock = this._aes.encrypt(block) + copyArray(this._lastCipherblock, ciphertext, i) + } + + return ciphertext + } + + ModeOfOperationCBC.prototype.decrypt = function (ciphertext) { + ciphertext = coerceArray(ciphertext) + + if (ciphertext.length % 16 !== 0) { + throw new Error('invalid ciphertext size (must be multiple of 16 bytes)') + } + + var plaintext = createArray(ciphertext.length) + var block = createArray(16) + + for (var i = 0; i < ciphertext.length; i += 16) { + copyArray(ciphertext, block, 0, i, i + 16) + block = this._aes.decrypt(block) + + for (var j = 0; j < 16; j++) { + plaintext[i + j] = block[j] ^ this._lastCipherblock[j] + } + + copyArray(ciphertext, this._lastCipherblock, 0, i, i + 16) + } + + return plaintext + } + + /** + * Mode Of Operation - Cipher Feedback (CFB) + */ + var ModeOfOperationCFB = function (key, iv, segmentSize) { + if (!(this instanceof ModeOfOperationCFB)) { + throw Error('AES must be instanitated with `new`') + } + + this.description = 'Cipher Feedback' + this.name = 'cfb' + + if (!iv) { + iv = createArray(16) + } else if (iv.length != 16) { + throw new Error('invalid initialation vector size (must be 16 size)') + } + + if (!segmentSize) { + segmentSize = 1 + } + + this.segmentSize = segmentSize + + this._shiftRegister = coerceArray(iv, true) + + this._aes = new AES(key) + } + + ModeOfOperationCFB.prototype.encrypt = function (plaintext) { + if (plaintext.length % this.segmentSize != 0) { + throw new Error('invalid plaintext size (must be segmentSize bytes)') + } + + var encrypted = coerceArray(plaintext, true) + + var xorSegment + for (var i = 0; i < encrypted.length; i += this.segmentSize) { + xorSegment = this._aes.encrypt(this._shiftRegister) + for (var j = 0; j < this.segmentSize; j++) { + encrypted[i + j] ^= xorSegment[j] + } + + // Shift the register + copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize) + copyArray( + encrypted, + this._shiftRegister, + 16 - this.segmentSize, + i, + i + this.segmentSize + ) + } + + return encrypted + } + + ModeOfOperationCFB.prototype.decrypt = function (ciphertext) { + if (ciphertext.length % this.segmentSize != 0) { + throw new Error('invalid ciphertext size (must be segmentSize bytes)') + } + + var plaintext = coerceArray(ciphertext, true) + + var xorSegment + for (var i = 0; i < plaintext.length; i += this.segmentSize) { + xorSegment = this._aes.encrypt(this._shiftRegister) + + for (var j = 0; j < this.segmentSize; j++) { + plaintext[i + j] ^= xorSegment[j] + } + + // Shift the register + copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize) + copyArray( + ciphertext, + this._shiftRegister, + 16 - this.segmentSize, + i, + i + this.segmentSize + ) + } + + return plaintext + } + + /** + * Mode Of Operation - Output Feedback (OFB) + */ + var ModeOfOperationOFB = function (key, iv) { + if (!(this instanceof ModeOfOperationOFB)) { + throw Error('AES must be instanitated with `new`') + } + + this.description = 'Output Feedback' + this.name = 'ofb' + + if (!iv) { + iv = createArray(16) + } else if (iv.length != 16) { + throw new Error('invalid initialation vector size (must be 16 bytes)') + } + + this._lastPrecipher = coerceArray(iv, true) + this._lastPrecipherIndex = 16 + + this._aes = new AES(key) + } + + ModeOfOperationOFB.prototype.encrypt = function (plaintext) { + var encrypted = coerceArray(plaintext, true) + + for (var i = 0; i < encrypted.length; i++) { + if (this._lastPrecipherIndex === 16) { + this._lastPrecipher = this._aes.encrypt(this._lastPrecipher) + this._lastPrecipherIndex = 0 + } + encrypted[i] ^= this._lastPrecipher[this._lastPrecipherIndex++] + } + + return encrypted + } + + // Decryption is symetric + ModeOfOperationOFB.prototype.decrypt = ModeOfOperationOFB.prototype.encrypt + + /** + * Counter object for CTR common mode of operation + */ + var Counter = function (initialValue) { + if (!(this instanceof Counter)) { + throw Error('Counter must be instanitated with `new`') + } + + // We allow 0, but anything false-ish uses the default 1 + if (initialValue !== 0 && !initialValue) { + initialValue = 1 + } + + if (typeof initialValue === 'number') { + this._counter = createArray(16) + this.setValue(initialValue) + } else { + this.setBytes(initialValue) + } + } + + Counter.prototype.setValue = function (value) { + if (typeof value !== 'number' || parseInt(value) != value) { + throw new Error('invalid counter value (must be an integer)') + } + + // We cannot safely handle numbers beyond the safe range for integers + if (value > Number.MAX_SAFE_INTEGER) { + throw new Error('integer value out of safe range') + } + + for (var index = 15; index >= 0; --index) { + this._counter[index] = value % 256 + value = parseInt(value / 256) + } + } + + Counter.prototype.setBytes = function (bytes) { + bytes = coerceArray(bytes, true) + + if (bytes.length != 16) { + throw new Error('invalid counter bytes size (must be 16 bytes)') + } + + this._counter = bytes + } + + Counter.prototype.increment = function () { + for (var i = 15; i >= 0; i--) { + if (this._counter[i] === 255) { + this._counter[i] = 0 + } else { + this._counter[i]++ + break + } + } + } + + /** + * Mode Of Operation - Counter (CTR) + */ + var ModeOfOperationCTR = function (key, counter) { + if (!(this instanceof ModeOfOperationCTR)) { + throw Error('AES must be instanitated with `new`') + } + + this.description = 'Counter' + this.name = 'ctr' + + if (!(counter instanceof Counter)) { + counter = new Counter(counter) + } + + this._counter = counter + + this._remainingCounter = null + this._remainingCounterIndex = 16 + + this._aes = new AES(key) + } + + ModeOfOperationCTR.prototype.encrypt = function (plaintext) { + var encrypted = coerceArray(plaintext, true) + + for (var i = 0; i < encrypted.length; i++) { + if (this._remainingCounterIndex === 16) { + this._remainingCounter = this._aes.encrypt(this._counter._counter) + this._remainingCounterIndex = 0 + this._counter.increment() + } + encrypted[i] ^= this._remainingCounter[this._remainingCounterIndex++] + } + + return encrypted + } + + // Decryption is symetric + ModeOfOperationCTR.prototype.decrypt = ModeOfOperationCTR.prototype.encrypt + + /////////////////////// + // Padding + + // See:https://tools.ietf.org/html/rfc2315 + function pkcs7pad(data) { + data = coerceArray(data, true) + var padder = 16 - (data.length % 16) + var result = createArray(data.length + padder) + copyArray(data, result) + for (var i = data.length; i < result.length; i++) { + result[i] = padder + } + return result + } + + function pkcs7strip(data) { + data = coerceArray(data, true) + if (data.length < 16) { + throw new Error('PKCS#7 invalid length') + } + + var padder = data[data.length - 1] + if (padder > 16) { + throw new Error('PKCS#7 padding byte out of range') + } + + var length = data.length - padder + for (var i = 0; i < padder; i++) { + if (data[length + i] !== padder) { + throw new Error('PKCS#7 invalid padding byte') + } + } + + var result = createArray(length) + copyArray(data, result, 0, 0, length) + return result + } + + /////////////////////// + // Exporting + + // The block cipher + var aesjs = { + AES: AES, + Counter: Counter, + + ModeOfOperation: { + ecb: ModeOfOperationECB, + cbc: ModeOfOperationCBC, + cfb: ModeOfOperationCFB, + ofb: ModeOfOperationOFB, + ctr: ModeOfOperationCTR + }, + + utils: { + hex: convertHex, + utf8: convertUtf8 + }, + + padding: { + pkcs7: { + pad: pkcs7pad, + strip: pkcs7strip + } + }, + + _arrayTest: { + coerceArray: coerceArray, + createArray: createArray, + copyArray: copyArray + } + } + + // node.js + if (typeof exports !== 'undefined') { + module.exports = aesjs + + // RequireJS/AMD + // http://www.requirejs.org/docs/api.html + // https://github.com/amdjs/amdjs-api/wiki/AMD + } else if (typeof define === 'function' && define.amd) { + define([], function () { + return aesjs + }) + + // Web Browsers + } else { + // If there was an existing library at "aesjs" make sure it's still available + if (root.aesjs) { + aesjs._aesjs = root.aesjs + } + + root.aesjs = aesjs + } +})(this) diff --git a/static/js/crypto/noble-secp256k1.js b/static/js/crypto/noble-secp256k1.js new file mode 100644 index 0000000..01148b0 --- /dev/null +++ b/static/js/crypto/noble-secp256k1.js @@ -0,0 +1,1178 @@ +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + ? factory(exports) + : typeof define === 'function' && define.amd + ? define(['exports'], factory) + : ((global = + typeof globalThis !== 'undefined' ? globalThis : global || self), + factory((global.nobleSecp256k1 = {}))) +})(this, function (exports) { + 'use strict' + + const _nodeResolve_empty = {} + + const nodeCrypto = /*#__PURE__*/ Object.freeze({ + __proto__: null, + default: _nodeResolve_empty + }) + + /*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */ + const _0n = BigInt(0) + const _1n = BigInt(1) + const _2n = BigInt(2) + const _3n = BigInt(3) + const _8n = BigInt(8) + const POW_2_256 = _2n ** BigInt(256) + const CURVE = { + a: _0n, + b: BigInt(7), + P: POW_2_256 - _2n ** BigInt(32) - BigInt(977), + n: POW_2_256 - BigInt('432420386565659656852420866394968145599'), + h: _1n, + Gx: BigInt( + '55066263022277343669578718895168534326250603453777594175500187360389116729240' + ), + Gy: BigInt( + '32670510020758816978083085130507043184471273380659243275938904335757337482424' + ), + beta: BigInt( + '0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee' + ) + } + function weistrass(x) { + const {a, b} = CURVE + const x2 = mod(x * x) + const x3 = mod(x2 * x) + return mod(x3 + a * x + b) + } + const USE_ENDOMORPHISM = CURVE.a === _0n + class JacobianPoint { + constructor(x, y, z) { + this.x = x + this.y = y + this.z = z + } + static fromAffine(p) { + if (!(p instanceof Point)) { + throw new TypeError('JacobianPoint#fromAffine: expected Point') + } + return new JacobianPoint(p.x, p.y, _1n) + } + static toAffineBatch(points) { + const toInv = invertBatch(points.map(p => p.z)) + return points.map((p, i) => p.toAffine(toInv[i])) + } + static normalizeZ(points) { + return JacobianPoint.toAffineBatch(points).map(JacobianPoint.fromAffine) + } + equals(other) { + if (!(other instanceof JacobianPoint)) + throw new TypeError('JacobianPoint expected') + const {x: X1, y: Y1, z: Z1} = this + const {x: X2, y: Y2, z: Z2} = other + const Z1Z1 = mod(Z1 ** _2n) + const Z2Z2 = mod(Z2 ** _2n) + const U1 = mod(X1 * Z2Z2) + const U2 = mod(X2 * Z1Z1) + const S1 = mod(mod(Y1 * Z2) * Z2Z2) + const S2 = mod(mod(Y2 * Z1) * Z1Z1) + return U1 === U2 && S1 === S2 + } + negate() { + return new JacobianPoint(this.x, mod(-this.y), this.z) + } + double() { + const {x: X1, y: Y1, z: Z1} = this + const A = mod(X1 ** _2n) + const B = mod(Y1 ** _2n) + const C = mod(B ** _2n) + const D = mod(_2n * (mod((X1 + B) ** _2n) - A - C)) + const E = mod(_3n * A) + const F = mod(E ** _2n) + const X3 = mod(F - _2n * D) + const Y3 = mod(E * (D - X3) - _8n * C) + const Z3 = mod(_2n * Y1 * Z1) + return new JacobianPoint(X3, Y3, Z3) + } + add(other) { + if (!(other instanceof JacobianPoint)) + throw new TypeError('JacobianPoint expected') + const {x: X1, y: Y1, z: Z1} = this + const {x: X2, y: Y2, z: Z2} = other + if (X2 === _0n || Y2 === _0n) return this + if (X1 === _0n || Y1 === _0n) return other + const Z1Z1 = mod(Z1 ** _2n) + const Z2Z2 = mod(Z2 ** _2n) + const U1 = mod(X1 * Z2Z2) + const U2 = mod(X2 * Z1Z1) + const S1 = mod(mod(Y1 * Z2) * Z2Z2) + const S2 = mod(mod(Y2 * Z1) * Z1Z1) + const H = mod(U2 - U1) + const r = mod(S2 - S1) + if (H === _0n) { + if (r === _0n) { + return this.double() + } else { + return JacobianPoint.ZERO + } + } + const HH = mod(H ** _2n) + const HHH = mod(H * HH) + const V = mod(U1 * HH) + const X3 = mod(r ** _2n - HHH - _2n * V) + const Y3 = mod(r * (V - X3) - S1 * HHH) + const Z3 = mod(Z1 * Z2 * H) + return new JacobianPoint(X3, Y3, Z3) + } + subtract(other) { + return this.add(other.negate()) + } + multiplyUnsafe(scalar) { + const P0 = JacobianPoint.ZERO + if (typeof scalar === 'bigint' && scalar === _0n) return P0 + let n = normalizeScalar(scalar) + if (n === _1n) return this + if (!USE_ENDOMORPHISM) { + let p = P0 + let d = this + while (n > _0n) { + if (n & _1n) p = p.add(d) + d = d.double() + n >>= _1n + } + return p + } + let {k1neg, k1, k2neg, k2} = splitScalarEndo(n) + let k1p = P0 + let k2p = P0 + let d = this + while (k1 > _0n || k2 > _0n) { + if (k1 & _1n) k1p = k1p.add(d) + if (k2 & _1n) k2p = k2p.add(d) + d = d.double() + k1 >>= _1n + k2 >>= _1n + } + if (k1neg) k1p = k1p.negate() + if (k2neg) k2p = k2p.negate() + k2p = new JacobianPoint(mod(k2p.x * CURVE.beta), k2p.y, k2p.z) + return k1p.add(k2p) + } + precomputeWindow(W) { + const windows = USE_ENDOMORPHISM ? 128 / W + 1 : 256 / W + 1 + const points = [] + let p = this + let base = p + for (let window = 0; window < windows; window++) { + base = p + points.push(base) + for (let i = 1; i < 2 ** (W - 1); i++) { + base = base.add(p) + points.push(base) + } + p = base.double() + } + return points + } + wNAF(n, affinePoint) { + if (!affinePoint && this.equals(JacobianPoint.BASE)) + affinePoint = Point.BASE + const W = (affinePoint && affinePoint._WINDOW_SIZE) || 1 + if (256 % W) { + throw new Error( + 'Point#wNAF: Invalid precomputation window, must be power of 2' + ) + } + let precomputes = affinePoint && pointPrecomputes.get(affinePoint) + if (!precomputes) { + precomputes = this.precomputeWindow(W) + if (affinePoint && W !== 1) { + precomputes = JacobianPoint.normalizeZ(precomputes) + pointPrecomputes.set(affinePoint, precomputes) + } + } + let p = JacobianPoint.ZERO + let f = JacobianPoint.ZERO + const windows = 1 + (USE_ENDOMORPHISM ? 128 / W : 256 / W) + const windowSize = 2 ** (W - 1) + const mask = BigInt(2 ** W - 1) + const maxNumber = 2 ** W + const shiftBy = BigInt(W) + for (let window = 0; window < windows; window++) { + const offset = window * windowSize + let wbits = Number(n & mask) + n >>= shiftBy + if (wbits > windowSize) { + wbits -= maxNumber + n += _1n + } + if (wbits === 0) { + let pr = precomputes[offset] + if (window % 2) pr = pr.negate() + f = f.add(pr) + } else { + let cached = precomputes[offset + Math.abs(wbits) - 1] + if (wbits < 0) cached = cached.negate() + p = p.add(cached) + } + } + return {p, f} + } + multiply(scalar, affinePoint) { + let n = normalizeScalar(scalar) + let point + let fake + if (USE_ENDOMORPHISM) { + const {k1neg, k1, k2neg, k2} = splitScalarEndo(n) + let {p: k1p, f: f1p} = this.wNAF(k1, affinePoint) + let {p: k2p, f: f2p} = this.wNAF(k2, affinePoint) + if (k1neg) k1p = k1p.negate() + if (k2neg) k2p = k2p.negate() + k2p = new JacobianPoint(mod(k2p.x * CURVE.beta), k2p.y, k2p.z) + point = k1p.add(k2p) + fake = f1p.add(f2p) + } else { + const {p, f} = this.wNAF(n, affinePoint) + point = p + fake = f + } + return JacobianPoint.normalizeZ([point, fake])[0] + } + toAffine(invZ = invert(this.z)) { + const {x, y, z} = this + const iz1 = invZ + const iz2 = mod(iz1 * iz1) + const iz3 = mod(iz2 * iz1) + const ax = mod(x * iz2) + const ay = mod(y * iz3) + const zz = mod(z * iz1) + if (zz !== _1n) throw new Error('invZ was invalid') + return new Point(ax, ay) + } + } + JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n) + JacobianPoint.ZERO = new JacobianPoint(_0n, _1n, _0n) + const pointPrecomputes = new WeakMap() + class Point { + constructor(x, y) { + this.x = x + this.y = y + } + _setWindowSize(windowSize) { + this._WINDOW_SIZE = windowSize + pointPrecomputes.delete(this) + } + static fromCompressedHex(bytes) { + const isShort = bytes.length === 32 + const x = bytesToNumber(isShort ? bytes : bytes.subarray(1)) + if (!isValidFieldElement(x)) throw new Error('Point is not on curve') + const y2 = weistrass(x) + let y = sqrtMod(y2) + const isYOdd = (y & _1n) === _1n + if (isShort) { + if (isYOdd) y = mod(-y) + } else { + const isFirstByteOdd = (bytes[0] & 1) === 1 + if (isFirstByteOdd !== isYOdd) y = mod(-y) + } + const point = new Point(x, y) + point.assertValidity() + return point + } + static fromUncompressedHex(bytes) { + const x = bytesToNumber(bytes.subarray(1, 33)) + const y = bytesToNumber(bytes.subarray(33, 65)) + const point = new Point(x, y) + point.assertValidity() + return point + } + static fromHex(hex) { + const bytes = ensureBytes(hex) + const len = bytes.length + const header = bytes[0] + if (len === 32 || (len === 33 && (header === 0x02 || header === 0x03))) { + return this.fromCompressedHex(bytes) + } + if (len === 65 && header === 0x04) return this.fromUncompressedHex(bytes) + throw new Error( + `Point.fromHex: received invalid point. Expected 32-33 compressed bytes or 65 uncompressed bytes, not ${len}` + ) + } + static fromPrivateKey(privateKey) { + return Point.BASE.multiply(normalizePrivateKey(privateKey)) + } + static fromSignature(msgHash, signature, recovery) { + msgHash = ensureBytes(msgHash) + const h = truncateHash(msgHash) + const {r, s} = normalizeSignature(signature) + if (recovery !== 0 && recovery !== 1) { + throw new Error('Cannot recover signature: invalid recovery bit') + } + const prefix = recovery & 1 ? '03' : '02' + const R = Point.fromHex(prefix + numTo32bStr(r)) + const {n} = CURVE + const rinv = invert(r, n) + const u1 = mod(-h * rinv, n) + const u2 = mod(s * rinv, n) + const Q = Point.BASE.multiplyAndAddUnsafe(R, u1, u2) + if (!Q) throw new Error('Cannot recover signature: point at infinify') + Q.assertValidity() + return Q + } + toRawBytes(isCompressed = false) { + return hexToBytes(this.toHex(isCompressed)) + } + toHex(isCompressed = false) { + const x = numTo32bStr(this.x) + if (isCompressed) { + const prefix = this.y & _1n ? '03' : '02' + return `${prefix}${x}` + } else { + return `04${x}${numTo32bStr(this.y)}` + } + } + toHexX() { + return this.toHex(true).slice(2) + } + toRawX() { + return this.toRawBytes(true).slice(1) + } + assertValidity() { + const msg = 'Point is not on elliptic curve' + const {x, y} = this + if (!isValidFieldElement(x) || !isValidFieldElement(y)) + throw new Error(msg) + const left = mod(y * y) + const right = weistrass(x) + if (mod(left - right) !== _0n) throw new Error(msg) + } + equals(other) { + return this.x === other.x && this.y === other.y + } + negate() { + return new Point(this.x, mod(-this.y)) + } + double() { + return JacobianPoint.fromAffine(this).double().toAffine() + } + add(other) { + return JacobianPoint.fromAffine(this) + .add(JacobianPoint.fromAffine(other)) + .toAffine() + } + subtract(other) { + return this.add(other.negate()) + } + multiply(scalar) { + return JacobianPoint.fromAffine(this).multiply(scalar, this).toAffine() + } + multiplyAndAddUnsafe(Q, a, b) { + const P = JacobianPoint.fromAffine(this) + const aP = + a === _0n || a === _1n || this !== Point.BASE + ? P.multiplyUnsafe(a) + : P.multiply(a) + const bQ = JacobianPoint.fromAffine(Q).multiplyUnsafe(b) + const sum = aP.add(bQ) + return sum.equals(JacobianPoint.ZERO) ? undefined : sum.toAffine() + } + } + Point.BASE = new Point(CURVE.Gx, CURVE.Gy) + Point.ZERO = new Point(_0n, _0n) + function sliceDER(s) { + return Number.parseInt(s[0], 16) >= 8 ? '00' + s : s + } + function parseDERInt(data) { + if (data.length < 2 || data[0] !== 0x02) { + throw new Error(`Invalid signature integer tag: ${bytesToHex(data)}`) + } + const len = data[1] + const res = data.subarray(2, len + 2) + if (!len || res.length !== len) { + throw new Error(`Invalid signature integer: wrong length`) + } + if (res[0] === 0x00 && res[1] <= 0x7f) { + throw new Error('Invalid signature integer: trailing length') + } + return {data: bytesToNumber(res), left: data.subarray(len + 2)} + } + function parseDERSignature(data) { + if (data.length < 2 || data[0] != 0x30) { + throw new Error(`Invalid signature tag: ${bytesToHex(data)}`) + } + if (data[1] !== data.length - 2) { + throw new Error('Invalid signature: incorrect length') + } + const {data: r, left: sBytes} = parseDERInt(data.subarray(2)) + const {data: s, left: rBytesLeft} = parseDERInt(sBytes) + if (rBytesLeft.length) { + throw new Error( + `Invalid signature: left bytes after parsing: ${bytesToHex(rBytesLeft)}` + ) + } + return {r, s} + } + class Signature { + constructor(r, s) { + this.r = r + this.s = s + this.assertValidity() + } + static fromCompact(hex) { + const arr = isUint8a(hex) + const name = 'Signature.fromCompact' + if (typeof hex !== 'string' && !arr) + throw new TypeError(`${name}: Expected string or Uint8Array`) + const str = arr ? bytesToHex(hex) : hex + if (str.length !== 128) throw new Error(`${name}: Expected 64-byte hex`) + return new Signature( + hexToNumber(str.slice(0, 64)), + hexToNumber(str.slice(64, 128)) + ) + } + static fromDER(hex) { + const arr = isUint8a(hex) + if (typeof hex !== 'string' && !arr) + throw new TypeError(`Signature.fromDER: Expected string or Uint8Array`) + const {r, s} = parseDERSignature(arr ? hex : hexToBytes(hex)) + return new Signature(r, s) + } + static fromHex(hex) { + return this.fromDER(hex) + } + assertValidity() { + const {r, s} = this + if (!isWithinCurveOrder(r)) + throw new Error('Invalid Signature: r must be 0 < r < n') + if (!isWithinCurveOrder(s)) + throw new Error('Invalid Signature: s must be 0 < s < n') + } + hasHighS() { + const HALF = CURVE.n >> _1n + return this.s > HALF + } + normalizeS() { + return this.hasHighS() ? new Signature(this.r, CURVE.n - this.s) : this + } + toDERRawBytes(isCompressed = false) { + return hexToBytes(this.toDERHex(isCompressed)) + } + toDERHex(isCompressed = false) { + const sHex = sliceDER(numberToHexUnpadded(this.s)) + if (isCompressed) return sHex + const rHex = sliceDER(numberToHexUnpadded(this.r)) + const rLen = numberToHexUnpadded(rHex.length / 2) + const sLen = numberToHexUnpadded(sHex.length / 2) + const length = numberToHexUnpadded(rHex.length / 2 + sHex.length / 2 + 4) + return `30${length}02${rLen}${rHex}02${sLen}${sHex}` + } + toRawBytes() { + return this.toDERRawBytes() + } + toHex() { + return this.toDERHex() + } + toCompactRawBytes() { + return hexToBytes(this.toCompactHex()) + } + toCompactHex() { + return numTo32bStr(this.r) + numTo32bStr(this.s) + } + } + function concatBytes(...arrays) { + if (!arrays.every(isUint8a)) throw new Error('Uint8Array list expected') + if (arrays.length === 1) return arrays[0] + const length = arrays.reduce((a, arr) => a + arr.length, 0) + const result = new Uint8Array(length) + for (let i = 0, pad = 0; i < arrays.length; i++) { + const arr = arrays[i] + result.set(arr, pad) + pad += arr.length + } + return result + } + function isUint8a(bytes) { + return bytes instanceof Uint8Array + } + const hexes = Array.from({length: 256}, (v, i) => + i.toString(16).padStart(2, '0') + ) + function bytesToHex(uint8a) { + if (!(uint8a instanceof Uint8Array)) throw new Error('Expected Uint8Array') + let hex = '' + for (let i = 0; i < uint8a.length; i++) { + hex += hexes[uint8a[i]] + } + return hex + } + function numTo32bStr(num) { + if (num > POW_2_256) throw new Error('Expected number < 2^256') + return num.toString(16).padStart(64, '0') + } + function numTo32b(num) { + return hexToBytes(numTo32bStr(num)) + } + function numberToHexUnpadded(num) { + const hex = num.toString(16) + return hex.length & 1 ? `0${hex}` : hex + } + function hexToNumber(hex) { + if (typeof hex !== 'string') { + throw new TypeError('hexToNumber: expected string, got ' + typeof hex) + } + return BigInt(`0x${hex}`) + } + function hexToBytes(hex) { + if (typeof hex !== 'string') { + throw new TypeError('hexToBytes: expected string, got ' + typeof hex) + } + if (hex.length % 2) + throw new Error('hexToBytes: received invalid unpadded hex' + hex.length) + const array = new Uint8Array(hex.length / 2) + for (let i = 0; i < array.length; i++) { + const j = i * 2 + const hexByte = hex.slice(j, j + 2) + const byte = Number.parseInt(hexByte, 16) + if (Number.isNaN(byte) || byte < 0) + throw new Error('Invalid byte sequence') + array[i] = byte + } + return array + } + function bytesToNumber(bytes) { + return hexToNumber(bytesToHex(bytes)) + } + function ensureBytes(hex) { + return hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes(hex) + } + function normalizeScalar(num) { + if (typeof num === 'number' && Number.isSafeInteger(num) && num > 0) + return BigInt(num) + if (typeof num === 'bigint' && isWithinCurveOrder(num)) return num + throw new TypeError('Expected valid private scalar: 0 < scalar < curve.n') + } + function mod(a, b = CURVE.P) { + const result = a % b + return result >= _0n ? result : b + result + } + function pow2(x, power) { + const {P} = CURVE + let res = x + while (power-- > _0n) { + res *= res + res %= P + } + return res + } + function sqrtMod(x) { + const {P} = CURVE + const _6n = BigInt(6) + const _11n = BigInt(11) + const _22n = BigInt(22) + const _23n = BigInt(23) + const _44n = BigInt(44) + const _88n = BigInt(88) + const b2 = (x * x * x) % P + const b3 = (b2 * b2 * x) % P + const b6 = (pow2(b3, _3n) * b3) % P + const b9 = (pow2(b6, _3n) * b3) % P + const b11 = (pow2(b9, _2n) * b2) % P + const b22 = (pow2(b11, _11n) * b11) % P + const b44 = (pow2(b22, _22n) * b22) % P + const b88 = (pow2(b44, _44n) * b44) % P + const b176 = (pow2(b88, _88n) * b88) % P + const b220 = (pow2(b176, _44n) * b44) % P + const b223 = (pow2(b220, _3n) * b3) % P + const t1 = (pow2(b223, _23n) * b22) % P + const t2 = (pow2(t1, _6n) * b2) % P + return pow2(t2, _2n) + } + function invert(number, modulo = CURVE.P) { + if (number === _0n || modulo <= _0n) { + throw new Error( + `invert: expected positive integers, got n=${number} mod=${modulo}` + ) + } + let a = mod(number, modulo) + let b = modulo + let x = _0n, + u = _1n + while (a !== _0n) { + const q = b / a + const r = b % a + const m = x - u * q + ;(b = a), (a = r), (x = u), (u = m) + } + const gcd = b + if (gcd !== _1n) throw new Error('invert: does not exist') + return mod(x, modulo) + } + function invertBatch(nums, p = CURVE.P) { + const scratch = new Array(nums.length) + const lastMultiplied = nums.reduce((acc, num, i) => { + if (num === _0n) return acc + scratch[i] = acc + return mod(acc * num, p) + }, _1n) + const inverted = invert(lastMultiplied, p) + nums.reduceRight((acc, num, i) => { + if (num === _0n) return acc + scratch[i] = mod(acc * scratch[i], p) + return mod(acc * num, p) + }, inverted) + return scratch + } + const divNearest = (a, b) => (a + b / _2n) / b + const POW_2_128 = _2n ** BigInt(128) + function splitScalarEndo(k) { + const {n} = CURVE + const a1 = BigInt('0x3086d221a7d46bcde86c90e49284eb15') + const b1 = -_1n * BigInt('0xe4437ed6010e88286f547fa90abfe4c3') + const a2 = BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8') + const b2 = a1 + const c1 = divNearest(b2 * k, n) + const c2 = divNearest(-b1 * k, n) + let k1 = mod(k - c1 * a1 - c2 * a2, n) + let k2 = mod(-c1 * b1 - c2 * b2, n) + const k1neg = k1 > POW_2_128 + const k2neg = k2 > POW_2_128 + if (k1neg) k1 = n - k1 + if (k2neg) k2 = n - k2 + if (k1 > POW_2_128 || k2 > POW_2_128) { + throw new Error('splitScalarEndo: Endomorphism failed, k=' + k) + } + return {k1neg, k1, k2neg, k2} + } + function truncateHash(hash) { + const {n} = CURVE + const byteLength = hash.length + const delta = byteLength * 8 - 256 + let h = bytesToNumber(hash) + if (delta > 0) h = h >> BigInt(delta) + if (h >= n) h -= n + return h + } + class HmacDrbg { + constructor() { + this.v = new Uint8Array(32).fill(1) + this.k = new Uint8Array(32).fill(0) + this.counter = 0 + } + hmac(...values) { + return utils.hmacSha256(this.k, ...values) + } + hmacSync(...values) { + if (typeof utils.hmacSha256Sync !== 'function') + throw new Error('utils.hmacSha256Sync is undefined, you need to set it') + const res = utils.hmacSha256Sync(this.k, ...values) + if (res instanceof Promise) + throw new Error('To use sync sign(), ensure utils.hmacSha256 is sync') + return res + } + incr() { + if (this.counter >= 1000) { + throw new Error('Tried 1,000 k values for sign(), all were invalid') + } + this.counter += 1 + } + async reseed(seed = new Uint8Array()) { + this.k = await this.hmac(this.v, Uint8Array.from([0x00]), seed) + this.v = await this.hmac(this.v) + if (seed.length === 0) return + this.k = await this.hmac(this.v, Uint8Array.from([0x01]), seed) + this.v = await this.hmac(this.v) + } + reseedSync(seed = new Uint8Array()) { + this.k = this.hmacSync(this.v, Uint8Array.from([0x00]), seed) + this.v = this.hmacSync(this.v) + if (seed.length === 0) return + this.k = this.hmacSync(this.v, Uint8Array.from([0x01]), seed) + this.v = this.hmacSync(this.v) + } + async generate() { + this.incr() + this.v = await this.hmac(this.v) + return this.v + } + generateSync() { + this.incr() + this.v = this.hmacSync(this.v) + return this.v + } + } + function isWithinCurveOrder(num) { + return _0n < num && num < CURVE.n + } + function isValidFieldElement(num) { + return _0n < num && num < CURVE.P + } + function kmdToSig(kBytes, m, d) { + const k = bytesToNumber(kBytes) + if (!isWithinCurveOrder(k)) return + const {n} = CURVE + const q = Point.BASE.multiply(k) + const r = mod(q.x, n) + if (r === _0n) return + const s = mod(invert(k, n) * mod(m + d * r, n), n) + if (s === _0n) return + const sig = new Signature(r, s) + const recovery = (q.x === sig.r ? 0 : 2) | Number(q.y & _1n) + return {sig, recovery} + } + function normalizePrivateKey(key) { + let num + if (typeof key === 'bigint') { + num = key + } else if ( + typeof key === 'number' && + Number.isSafeInteger(key) && + key > 0 + ) { + num = BigInt(key) + } else if (typeof key === 'string') { + if (key.length !== 64) throw new Error('Expected 32 bytes of private key') + num = hexToNumber(key) + } else if (isUint8a(key)) { + if (key.length !== 32) throw new Error('Expected 32 bytes of private key') + num = bytesToNumber(key) + } else { + throw new TypeError('Expected valid private key') + } + if (!isWithinCurveOrder(num)) + throw new Error('Expected private key: 0 < key < n') + return num + } + function normalizePublicKey(publicKey) { + if (publicKey instanceof Point) { + publicKey.assertValidity() + return publicKey + } else { + return Point.fromHex(publicKey) + } + } + function normalizeSignature(signature) { + if (signature instanceof Signature) { + signature.assertValidity() + return signature + } + try { + return Signature.fromDER(signature) + } catch (error) { + return Signature.fromCompact(signature) + } + } + function getPublicKey(privateKey, isCompressed = false) { + return Point.fromPrivateKey(privateKey).toRawBytes(isCompressed) + } + function recoverPublicKey( + msgHash, + signature, + recovery, + isCompressed = false + ) { + return Point.fromSignature(msgHash, signature, recovery).toRawBytes( + isCompressed + ) + } + function isPub(item) { + const arr = isUint8a(item) + const str = typeof item === 'string' + const len = (arr || str) && item.length + if (arr) return len === 33 || len === 65 + if (str) return len === 66 || len === 130 + if (item instanceof Point) return true + return false + } + function getSharedSecret(privateA, publicB, isCompressed = false) { + if (isPub(privateA)) + throw new TypeError('getSharedSecret: first arg must be private key') + if (!isPub(publicB)) + throw new TypeError('getSharedSecret: second arg must be public key') + const b = normalizePublicKey(publicB) + b.assertValidity() + return b.multiply(normalizePrivateKey(privateA)).toRawBytes(isCompressed) + } + function bits2int(bytes) { + const slice = bytes.length > 32 ? bytes.slice(0, 32) : bytes + return bytesToNumber(slice) + } + function bits2octets(bytes) { + const z1 = bits2int(bytes) + const z2 = mod(z1, CURVE.n) + return int2octets(z2 < _0n ? z1 : z2) + } + function int2octets(num) { + if (typeof num !== 'bigint') throw new Error('Expected bigint') + const hex = numTo32bStr(num) + return hexToBytes(hex) + } + function initSigArgs(msgHash, privateKey, extraEntropy) { + if (msgHash == null) + throw new Error(`sign: expected valid message hash, not "${msgHash}"`) + const h1 = ensureBytes(msgHash) + const d = normalizePrivateKey(privateKey) + const seedArgs = [int2octets(d), bits2octets(h1)] + if (extraEntropy != null) { + if (extraEntropy === true) extraEntropy = utils.randomBytes(32) + const e = ensureBytes(extraEntropy) + if (e.length !== 32) + throw new Error('sign: Expected 32 bytes of extra data') + seedArgs.push(e) + } + const seed = concatBytes(...seedArgs) + const m = bits2int(h1) + return {seed, m, d} + } + function finalizeSig(recSig, opts) { + let {sig, recovery} = recSig + const {canonical, der, recovered} = Object.assign( + {canonical: true, der: true}, + opts + ) + if (canonical && sig.hasHighS()) { + sig = sig.normalizeS() + recovery ^= 1 + } + const hashed = der ? sig.toDERRawBytes() : sig.toCompactRawBytes() + return recovered ? [hashed, recovery] : hashed + } + async function sign(msgHash, privKey, opts = {}) { + const {seed, m, d} = initSigArgs(msgHash, privKey, opts.extraEntropy) + let sig + const drbg = new HmacDrbg() + await drbg.reseed(seed) + while (!(sig = kmdToSig(await drbg.generate(), m, d))) await drbg.reseed() + return finalizeSig(sig, opts) + } + function signSync(msgHash, privKey, opts = {}) { + const {seed, m, d} = initSigArgs(msgHash, privKey, opts.extraEntropy) + let sig + const drbg = new HmacDrbg() + drbg.reseedSync(seed) + while (!(sig = kmdToSig(drbg.generateSync(), m, d))) drbg.reseedSync() + return finalizeSig(sig, opts) + } + const vopts = {strict: true} + function verify(signature, msgHash, publicKey, opts = vopts) { + let sig + try { + sig = normalizeSignature(signature) + msgHash = ensureBytes(msgHash) + } catch (error) { + return false + } + const {r, s} = sig + if (opts.strict && sig.hasHighS()) return false + const h = truncateHash(msgHash) + let P + try { + P = normalizePublicKey(publicKey) + } catch (error) { + return false + } + const {n} = CURVE + const sinv = invert(s, n) + const u1 = mod(h * sinv, n) + const u2 = mod(r * sinv, n) + const R = Point.BASE.multiplyAndAddUnsafe(P, u1, u2) + if (!R) return false + const v = mod(R.x, n) + return v === r + } + function finalizeSchnorrChallenge(ch) { + return mod(bytesToNumber(ch), CURVE.n) + } + function hasEvenY(point) { + return (point.y & _1n) === _0n + } + class SchnorrSignature { + constructor(r, s) { + this.r = r + this.s = s + this.assertValidity() + } + static fromHex(hex) { + const bytes = ensureBytes(hex) + if (bytes.length !== 64) + throw new TypeError( + `SchnorrSignature.fromHex: expected 64 bytes, not ${bytes.length}` + ) + const r = bytesToNumber(bytes.subarray(0, 32)) + const s = bytesToNumber(bytes.subarray(32, 64)) + return new SchnorrSignature(r, s) + } + assertValidity() { + const {r, s} = this + if (!isValidFieldElement(r) || !isWithinCurveOrder(s)) + throw new Error('Invalid signature') + } + toHex() { + return numTo32bStr(this.r) + numTo32bStr(this.s) + } + toRawBytes() { + return hexToBytes(this.toHex()) + } + } + function schnorrGetPublicKey(privateKey) { + return Point.fromPrivateKey(privateKey).toRawX() + } + function initSchnorrSigArgs(message, privateKey, auxRand) { + if (message == null) + throw new TypeError(`sign: Expected valid message, not "${message}"`) + const m = ensureBytes(message) + const d0 = normalizePrivateKey(privateKey) + const rand = ensureBytes(auxRand) + if (rand.length !== 32) + throw new TypeError('sign: Expected 32 bytes of aux randomness') + const P = Point.fromPrivateKey(d0) + const px = P.toRawX() + const d = hasEvenY(P) ? d0 : CURVE.n - d0 + return {m, P, px, d, rand} + } + function initSchnorrNonce(d, t0h) { + return numTo32b(d ^ bytesToNumber(t0h)) + } + function finalizeSchnorrNonce(k0h) { + const k0 = mod(bytesToNumber(k0h), CURVE.n) + if (k0 === _0n) + throw new Error('sign: Creation of signature failed. k is zero') + const R = Point.fromPrivateKey(k0) + const rx = R.toRawX() + const k = hasEvenY(R) ? k0 : CURVE.n - k0 + return {R, rx, k} + } + function finalizeSchnorrSig(R, k, e, d) { + return new SchnorrSignature(R.x, mod(k + e * d, CURVE.n)).toRawBytes() + } + async function schnorrSign( + message, + privateKey, + auxRand = utils.randomBytes() + ) { + const {m, px, d, rand} = initSchnorrSigArgs(message, privateKey, auxRand) + const t = initSchnorrNonce(d, await utils.taggedHash(TAGS.aux, rand)) + const {R, rx, k} = finalizeSchnorrNonce( + await utils.taggedHash(TAGS.nonce, t, px, m) + ) + const e = finalizeSchnorrChallenge( + await utils.taggedHash(TAGS.challenge, rx, px, m) + ) + const sig = finalizeSchnorrSig(R, k, e, d) + const isValid = await schnorrVerify(sig, m, px) + if (!isValid) throw new Error('sign: Invalid signature produced') + return sig + } + function schnorrSignSync(message, privateKey, auxRand = utils.randomBytes()) { + const {m, px, d, rand} = initSchnorrSigArgs(message, privateKey, auxRand) + const t = initSchnorrNonce(d, utils.taggedHashSync(TAGS.aux, rand)) + const {R, rx, k} = finalizeSchnorrNonce( + utils.taggedHashSync(TAGS.nonce, t, px, m) + ) + const e = finalizeSchnorrChallenge( + utils.taggedHashSync(TAGS.challenge, rx, px, m) + ) + const sig = finalizeSchnorrSig(R, k, e, d) + const isValid = schnorrVerifySync(sig, m, px) + if (!isValid) throw new Error('sign: Invalid signature produced') + return sig + } + function initSchnorrVerify(signature, message, publicKey) { + const raw = signature instanceof SchnorrSignature + const sig = raw ? signature : SchnorrSignature.fromHex(signature) + if (raw) sig.assertValidity() + return { + ...sig, + m: ensureBytes(message), + P: normalizePublicKey(publicKey) + } + } + function finalizeSchnorrVerify(r, P, s, e) { + const R = Point.BASE.multiplyAndAddUnsafe( + P, + normalizePrivateKey(s), + mod(-e, CURVE.n) + ) + if (!R || !hasEvenY(R) || R.x !== r) return false + return true + } + async function schnorrVerify(signature, message, publicKey) { + try { + const {r, s, m, P} = initSchnorrVerify(signature, message, publicKey) + const e = finalizeSchnorrChallenge( + await utils.taggedHash(TAGS.challenge, numTo32b(r), P.toRawX(), m) + ) + return finalizeSchnorrVerify(r, P, s, e) + } catch (error) { + return false + } + } + function schnorrVerifySync(signature, message, publicKey) { + try { + const {r, s, m, P} = initSchnorrVerify(signature, message, publicKey) + const e = finalizeSchnorrChallenge( + utils.taggedHashSync(TAGS.challenge, numTo32b(r), P.toRawX(), m) + ) + return finalizeSchnorrVerify(r, P, s, e) + } catch (error) { + return false + } + } + const schnorr = { + Signature: SchnorrSignature, + getPublicKey: schnorrGetPublicKey, + sign: schnorrSign, + verify: schnorrVerify, + signSync: schnorrSignSync, + verifySync: schnorrVerifySync + } + Point.BASE._setWindowSize(8) + const crypto = { + node: nodeCrypto, + web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined + } + const TAGS = { + challenge: 'BIP0340/challenge', + aux: 'BIP0340/aux', + nonce: 'BIP0340/nonce' + } + const TAGGED_HASH_PREFIXES = {} + const utils = { + isValidPrivateKey(privateKey) { + try { + normalizePrivateKey(privateKey) + return true + } catch (error) { + return false + } + }, + privateAdd: (privateKey, tweak) => { + const p = normalizePrivateKey(privateKey) + const t = normalizePrivateKey(tweak) + return numTo32b(mod(p + t, CURVE.n)) + }, + privateNegate: privateKey => { + const p = normalizePrivateKey(privateKey) + return numTo32b(CURVE.n - p) + }, + pointAddScalar: (p, tweak, isCompressed) => { + const P = Point.fromHex(p) + const t = normalizePrivateKey(tweak) + const Q = Point.BASE.multiplyAndAddUnsafe(P, t, _1n) + if (!Q) throw new Error('Tweaked point at infinity') + return Q.toRawBytes(isCompressed) + }, + pointMultiply: (p, tweak, isCompressed) => { + const P = Point.fromHex(p) + const t = bytesToNumber(ensureBytes(tweak)) + return P.multiply(t).toRawBytes(isCompressed) + }, + hashToPrivateKey: hash => { + hash = ensureBytes(hash) + if (hash.length < 40 || hash.length > 1024) + throw new Error('Expected 40-1024 bytes of private key as per FIPS 186') + const num = mod(bytesToNumber(hash), CURVE.n - _1n) + _1n + return numTo32b(num) + }, + randomBytes: (bytesLength = 32) => { + if (crypto.web) { + return crypto.web.getRandomValues(new Uint8Array(bytesLength)) + } else if (crypto.node) { + const {randomBytes} = crypto.node + return Uint8Array.from(randomBytes(bytesLength)) + } else { + throw new Error("The environment doesn't have randomBytes function") + } + }, + randomPrivateKey: () => { + return utils.hashToPrivateKey(utils.randomBytes(40)) + }, + bytesToHex, + hexToBytes, + concatBytes, + mod, + invert, + sha256: async (...messages) => { + if (crypto.web) { + const buffer = await crypto.web.subtle.digest( + 'SHA-256', + concatBytes(...messages) + ) + return new Uint8Array(buffer) + } else if (crypto.node) { + const {createHash} = crypto.node + const hash = createHash('sha256') + messages.forEach(m => hash.update(m)) + return Uint8Array.from(hash.digest()) + } else { + throw new Error("The environment doesn't have sha256 function") + } + }, + hmacSha256: async (key, ...messages) => { + if (crypto.web) { + const ckey = await crypto.web.subtle.importKey( + 'raw', + key, + {name: 'HMAC', hash: {name: 'SHA-256'}}, + false, + ['sign'] + ) + const message = concatBytes(...messages) + const buffer = await crypto.web.subtle.sign('HMAC', ckey, message) + return new Uint8Array(buffer) + } else if (crypto.node) { + const {createHmac} = crypto.node + const hash = createHmac('sha256', key) + messages.forEach(m => hash.update(m)) + return Uint8Array.from(hash.digest()) + } else { + throw new Error("The environment doesn't have hmac-sha256 function") + } + }, + sha256Sync: undefined, + hmacSha256Sync: undefined, + taggedHash: async (tag, ...messages) => { + let tagP = TAGGED_HASH_PREFIXES[tag] + if (tagP === undefined) { + const tagH = await utils.sha256( + Uint8Array.from(tag, c => c.charCodeAt(0)) + ) + tagP = concatBytes(tagH, tagH) + TAGGED_HASH_PREFIXES[tag] = tagP + } + return utils.sha256(tagP, ...messages) + }, + taggedHashSync: (tag, ...messages) => { + if (typeof utils.sha256Sync !== 'function') + throw new Error('utils.sha256Sync is undefined, you need to set it') + let tagP = TAGGED_HASH_PREFIXES[tag] + if (tagP === undefined) { + const tagH = utils.sha256Sync( + Uint8Array.from(tag, c => c.charCodeAt(0)) + ) + tagP = concatBytes(tagH, tagH) + TAGGED_HASH_PREFIXES[tag] = tagP + } + return utils.sha256Sync(tagP, ...messages) + }, + precompute(windowSize = 8, point = Point.BASE) { + const cached = point === Point.BASE ? point : new Point(point.x, point.y) + cached._setWindowSize(windowSize) + cached.multiply(_3n) + return cached + } + } + + exports.CURVE = CURVE + exports.Point = Point + exports.Signature = Signature + exports.getPublicKey = getPublicKey + exports.getSharedSecret = getSharedSecret + exports.recoverPublicKey = recoverPublicKey + exports.schnorr = schnorr + exports.sign = sign + exports.signSync = signSync + exports.utils = utils + exports.verify = verify + + Object.defineProperty(exports, '__esModule', {value: true}) +}) diff --git a/static/js/index.js b/static/js/index.js index a6ca6d2..c0abda7 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -1,86 +1,434 @@ -const mapObject = obj => { - // obj.date = Quasar.date.formatDate(new Date(obj.time), 'YYYY-MM-DD HH:mm') - // here you can do something with the mapped data - return obj -} - +// TODO were was this needed? +// Vue.filter('reverse', function (value) { +// // slice to make a copy of array, then reverse the copy +// return value.slice().reverse() +// }) window.app = Vue.createApp({ el: '#vue', - mixins: [windowMixin], - // Declare models/variables + mixins: [window.windowMixin], data() { return { - protocol: window.location.protocol, - location: '//' + window.location.hostname, - thingDialog: { + scan: { + scanning: false, + scanCount: 0, + scanIndex: 0 + }, + + currentAddress: null, + + tab: 'addresses', + + config: {sats_denominated: true}, + + qrCodeDialog: { show: false, - data: {} + data: null }, - someBool: true, - splitterModel: 20, - exampleData: [], - tab: 'frameworks', - framworktab: 'fastapi', - usefultab: 'magicalg', - vettedData: '', - baseUrl: window.location.origin + ...tables, + ...tableData, + + walletAccounts: [], + addresses: [], + history: [], + historyFilter: '', + + showAddress: false, + addressNote: '', + showPayment: false, + fetchedUtxos: false, + utxosFilter: '', + network: null, + + showEnterSignedPsbt: false, + signedBase64Psbt: null, + + connectedDeviceType: null + } + }, + computed: { + mempoolHostname: function () { + if (!this.config.isLoaded) return + let hostname = new URL(this.config.mempool_endpoint).hostname + if (this.config.network === 'Testnet') { + hostname += '/testnet' + } + return hostname + }, + signerDevice: function () { + if (this.connectedDeviceType === 'trezor-device') { + return this.$refs.trezorSigner + } + return this.$refs.serialSigner } }, - // Where functions live + methods: { - exampleFunction(data) { - LNbits.api - .request( - 'GET', // Type of request - '/example/api/v1/test/00000000', // URL of the endpoint - this.g.user.wallets[0].inkey, // Often endpoints require a key - data + updateAmountForAddress: async function (addressData, amount = 0) { + try { + const wallet = this.g.user.wallets[0] + addressData.amount = amount + if (!addressData.isChange) { + const addressWallet = this.walletAccounts.find( + w => w.id === addressData.wallet + ) + if ( + addressWallet && + addressWallet.address_no < addressData.addressIndex + ) { + addressWallet.address_no = addressData.addressIndex + } + } + + // todo: account deleted + await LNbits.api.request( + 'PUT', + `/watchonly/api/v1/address/${addressData.id}`, + wallet.adminkey, + {amount} + ) + } catch (err) { + addressData.error = 'Failed to refresh amount for address' + this.$q.notify({ + type: 'warning', + message: `Failed to refresh amount for address ${addressData.address}`, + timeout: 10000 + }) + LNbits.utils.notifyApiError(err) + } + }, + updateNoteForAddress: async function ({addressId, note}) { + try { + const wallet = this.g.user.wallets[0] + await LNbits.api.request( + 'PUT', + `/watchonly/api/v1/address/${addressId}`, + wallet.adminkey, + {note} + ) + const updatedAddress = + this.addresses.find(a => a.id === addressId) || {} + updatedAddress.note = note + } catch (err) { + LNbits.utils.notifyApiError(err) + } + }, + + //################### ADDRESS HISTORY ################### + addressHistoryFromTxs: function (addressData, txs) { + const addressHistory = [] + txs.forEach(tx => { + const sent = tx.vin + .filter( + vin => vin.prevout.scriptpubkey_address === addressData.address + ) + .map(vin => mapInputToSentHistory(tx, addressData, vin)) + + const received = tx.vout + .filter(vout => vout.scriptpubkey_address === addressData.address) + .map(vout => mapOutputToReceiveHistory(tx, addressData, vout)) + addressHistory.push(...sent, ...received) + }) + return addressHistory + }, + + markSameTxAddressHistory: function () { + this.history + .filter(s => s.sent) + .forEach((el, i, arr) => { + if (el.isSubItem) return + + const sameTxItems = arr.slice(i + 1).filter(e => e.txId === el.txId) + if (!sameTxItems.length) return + sameTxItems.forEach(e => { + e.isSubItem = true + }) + + el.totalAmount = + el.amount + sameTxItems.reduce((t, e) => (t += e.amount || 0), 0) + el.sameTxItems = sameTxItems + }) + }, + + //################### PAYMENT ################### + + initPaymentData: async function () { + if (!this.payment.show) return + await this.refreshAddresses() + }, + + goToPaymentView: async function () { + this.showPayment = true + await this.initPaymentData() + }, + + //################### PSBT ################### + + updateSignedPsbt: async function (psbtBase64) { + this.$refs.paymentRef.updateSignedPsbt(psbtBase64) + }, + + updateSignedTx: async function (txHex) { + this.$refs.paymentRef.updateSignedTx(txHex) + }, + + showEnterSignedPsbtDialog: function () { + this.signedBase64Psbt = '' + this.showEnterSignedPsbt = true + }, + + checkPsbt: function () { + this.$refs.paymentRef.updateSignedPsbt(this.signedBase64Psbt) + }, + + //################### UTXOs ################### + scanAllAddresses: async function () { + await this.refreshAddresses() + this.history = [] + let addresses = this.addresses + this.utxos.data = [] + this.utxos.total = 0 + // Loop while new funds are found on the gap adresses. + // Use 1000 limit as a safety check (scan 20 000 addresses max) + for (let i = 0; i < 1000 && addresses.length; i++) { + await this.updateUtxosForAddresses(addresses) + const oldAddresses = this.addresses.slice() + await this.refreshAddresses() + const newAddresses = this.addresses.slice() + // check if gap addresses have been extended + addresses = newAddresses.filter( + newAddr => !oldAddresses.find(oldAddr => oldAddr.id === newAddr.id) + ) + if (addresses.length) { + this.$q.notify({ + type: 'positive', + message: 'Funds found! Scanning for more...', + timeout: 10000 + }) + } + } + }, + scanAddressWithAmount: async function () { + this.utxos.data = [] + this.utxos.total = 0 + this.history = [] + const addresses = this.addresses.filter(a => a.hasActivity) + await this.updateUtxosForAddresses(addresses) + }, + scanAddress: async function (addressData) { + this.updateUtxosForAddresses([addressData]) + this.$q.notify({ + type: 'positive', + message: 'Address Rescanned', + timeout: 10000 + }) + }, + refreshAddresses: async function () { + if (!this.walletAccounts) return + this.addresses = [] + for (const {id, type} of this.walletAccounts) { + const newAddresses = await this.getAddressesForWallet(id) + const uniqueAddresses = newAddresses.filter( + newAddr => !this.addresses.find(a => a.address === newAddr.address) + ) + + const lastActiveAddress = + uniqueAddresses.filter(a => !a.isChange && a.hasActivity).pop() || {} + + uniqueAddresses.forEach(a => { + a.expanded = false + a.accountType = type + a.gapLimitExceeded = + !a.isChange && + a.addressIndex > + lastActiveAddress.addressIndex + DEFAULT_RECEIVE_GAP_LIMIT + }) + this.addresses.push(...uniqueAddresses) + } + this.$emit('update:addresses', this.addresses) + }, + getAddressesForWallet: async function (walletId) { + try { + const {data} = await LNbits.api.request( + 'GET', + '/watchonly/api/v1/addresses/' + walletId, + this.g.user.wallets[0].inkey ) - .then(response => { - this.exampleData.push(mapObject(response.data)) // Often whats returned is mapped onto some model + return data.map(mapAddressesData) + } catch (error) { + this.$q.notify({ + type: 'warning', + message: `Failed to fetch addresses for wallet with id ${walletId}.`, + timeout: 10000 }) - // Error will be passed to the frontend - .catch(LNbits.utils.notifyApiError) - }, - getVettedReadme() { - // This is a function that gets the vetted readme from the LNbits repo and converts it from makrdown to html. - LNbits.api - .request('GET', '/example/api/v1/vetted', this.g.user.wallets[0].inkey) - .then(response => { - this.vettedData = LNbits.utils.convertMarkdown(response.data) + LNbits.utils.notifyApiError(error) + } + return [] + }, + updateUtxosForAddresses: async function (addresses = []) { + this.scan = {scanning: true, scanCount: addresses.length, scanIndex: 0} + + try { + for (addrData of addresses) { + const addressHistory = await this.getAddressTxsDelayed(addrData) + // remove old entries + this.history = this.history.filter( + h => h.address !== addrData.address + ) + + // add new entries + this.history.push(...addressHistory) + this.history.sort((a, b) => (!a.height ? -1 : b.height - a.height)) + this.markSameTxAddressHistory() + + if (addressHistory.length) { + // search only if it ever had any activity + const utxos = await this.getAddressTxsUtxoDelayed(addrData.address) + this.updateUtxosForAddress(addrData, utxos) + } + + this.scan.scanIndex++ + } + } catch (error) { + console.error(error) + this.$q.notify({ + type: 'warning', + message: 'Failed to scan addresses', + timeout: 10000 }) - .catch(LNbits.utils.notifyApiError) - }, - async initWs() { - if (location.protocol !== 'http:') { - localUrl = - 'wss://' + - document.domain + - ':' + - location.port + - '/api/v1/ws/32872r23g29' - } else { - localUrl = - 'ws://' + - document.domain + - ':' + - location.port + - '/api/v1/ws/32872r23g29' + } finally { + this.scan.scanning = false + } + }, + updateUtxosForAddress: function (addressData, utxos = []) { + const wallet = + this.walletAccounts.find(w => w.id === addressData.wallet) || {} + + const newUtxos = utxos.map(utxo => + mapAddressDataToUtxo(wallet, addressData, utxo) + ) + // remove old utxos + this.utxos.data = this.utxos.data.filter( + u => u.address !== addressData.address + ) + // add new utxos + this.utxos.data.push(...newUtxos) + if (utxos.length) { + this.utxos.data.sort((a, b) => b.sort - a.sort) + this.utxos.total = this.utxos.data.reduce( + (total, y) => (total += y?.amount || 0), + 0 + ) } - this.ws = new WebSocket(localUrl) - this.ws.addEventListener('message', async ({data}) => { - const res = data.toString() - document.getElementById('text-to-change').innerHTML = res + const addressTotal = utxos.reduce( + (total, y) => (total += y?.value || 0), + 0 + ) + this.updateAmountForAddress(addressData, addressTotal) + }, + + //################### MEMPOOL API ################### + getAddressTxsDelayed: async function (addrData) { + const accounts = this.walletAccounts + const { + bitcoin: {addresses: addressesAPI} + } = mempoolJS({ + hostname: this.mempoolHostname + }) + const fn = async () => { + if (!accounts.find(w => w.id === addrData.wallet)) return [] + return addressesAPI.getAddressTxs({ + address: addrData.address + }) + } + const addressTxs = await retryWithDelay(fn) + return this.addressHistoryFromTxs(addrData, addressTxs) + }, + + getAddressTxsUtxoDelayed: async function (address) { + const endpoint = this.mempoolHostname + const { + bitcoin: {addresses: addressesAPI} + } = mempoolJS({ + hostname: endpoint }) + + const fn = async () => { + if (endpoint !== this.mempoolHostname) return [] + return addressesAPI.getAddressTxsUtxo({ + address + }) + } + return retryWithDelay(fn) + }, + + openQrCodeDialog: function (addressData) { + this.currentAddress = addressData + this.addressNote = addressData.note || '' + this.showAddress = true + }, + searchInTab: function ({tab, value}) { + this.tab = tab + this[`${tab}Filter`] = value }, - sendThingDialog() { - console.log(this.thingDialog) + + updateAccounts: async function (accounts) { + this.walletAccounts = accounts + await this.refreshAddresses() + await this.scanAddressWithAmount() + }, + showAddressDetails: function (addressData) { + this.openQrCodeDialog(addressData) + }, + showAddressDetailsWithConfirmation: function ({addressData, wallet}) { + this.showAddressDetails(addressData) + if (this.$refs.serialSigner.isConnected()) { + if (this.$refs.serialSigner.isAuthenticated()) { + if (wallet.meta?.accountPath) { + const branchIndex = addressData.isChange ? 1 : 0 + const path = + wallet.meta.accountPath + + `/${branchIndex}/${addressData.addressIndex}` + this.$refs.serialSigner.hwwShowAddress(path, addressData.address) + } + } else { + this.$q.notify({ + type: 'warning', + message: 'Please login in order to confirm address on device', + timeout: 10000 + }) + } + } + }, + initUtxos: function (addresses) { + if (!this.fetchedUtxos && addresses.length) { + this.fetchedUtxos = true + this.addresses = addresses + this.scanAddressWithAmount() + } + }, + handleBroadcastSuccess: async function (txId) { + this.tab = 'history' + this.searchInTab({tab: 'history', value: txId}) + this.showPayment = false + await this.refreshAddresses() + await this.scanAddressWithAmount() + }, + handleDeviceConnected: async function (deviceType) { + this.connectedDeviceType = deviceType } }, - // To run on startup - created() { - this.exampleFunction('lorum') - this.initWs() - this.getVettedReadme() + created: async function () { + if (this.g.user.wallets.length) { + await this.refreshAddresses() + await this.scanAddressWithAmount() + } + + await TrezorConnect.init({ + lazyLoad: true, // this param will prevent iframe injection until TrezorConnect.method will be called + manifest: { + email: 'vlad@lnbits.com', + appUrl: 'http://lnbits.com' + } + }) } }) diff --git a/static/js/map.js b/static/js/map.js new file mode 100644 index 0000000..7b13c4b --- /dev/null +++ b/static/js/map.js @@ -0,0 +1,81 @@ +const mapAddressesData = a => ({ + id: a.id, + address: a.address, + amount: a.amount, + wallet: a.wallet, + note: a.note, + + isChange: a.branch_index === 1, + addressIndex: a.address_index, + hasActivity: a.has_activity +}) + +const mapInputToSentHistory = (tx, addressData, vin) => ({ + sent: true, + txId: tx.txid, + address: addressData.address, + isChange: addressData.isChange, + amount: vin.prevout.value, + date: blockTimeToDate(tx.status.block_time), + height: tx.status.block_height, + confirmed: tx.status.confirmed, + fee: tx.fee, + expanded: false +}) + +const mapOutputToReceiveHistory = (tx, addressData, vout) => ({ + received: true, + txId: tx.txid, + address: addressData.address, + isChange: addressData.isChange, + amount: vout.value, + date: blockTimeToDate(tx.status.block_time), + height: tx.status.block_height, + confirmed: tx.status.confirmed, + fee: tx.fee, + expanded: false +}) + +const mapUtxoToPsbtInput = utxo => ({ + tx_id: utxo.txId, + vout: utxo.vout, + amount: utxo.amount, + address: utxo.address, + branch_index: utxo.isChange ? 1 : 0, + address_index: utxo.addressIndex, + wallet: utxo.wallet, + accountType: utxo.accountType, + accountPath: utxo.accountPath, + txHex: '' +}) + +const mapAddressDataToUtxo = (wallet, addressData, utxo) => ({ + id: addressData.id, + address: addressData.address, + isChange: addressData.isChange, + addressIndex: addressData.addressIndex, + wallet: addressData.wallet, + accountType: addressData.accountType, + accountPath: wallet.meta.accountPath, + masterpubFingerprint: wallet.fingerprint, + txId: utxo.txid, + vout: utxo.vout, + confirmed: utxo.status.confirmed, + amount: utxo.value, + date: blockTimeToDate(utxo.status?.block_time), + sort: utxo.status?.block_time, + expanded: false, + selected: false +}) + +const mapWalletAccount = function (o) { + return Object.assign({}, o, { + id: o.id, + title: o.title, + hr_address: o.hr_address, + last_height: o.last_height, + balance: o.balance, + expanded: false + }) +} + diff --git a/static/js/tables.js b/static/js/tables.js new file mode 100644 index 0000000..f437bcd --- /dev/null +++ b/static/js/tables.js @@ -0,0 +1,61 @@ +const tables = { + summaryTable: { + columns: [ + { + name: 'totalInputs', + align: 'center', + label: 'Selected Amount' + }, + { + name: 'totalOutputs', + align: 'center', + label: 'Payed Amount' + }, + { + name: 'fees', + align: 'center', + label: 'Fees' + }, + { + name: 'change', + align: 'center', + label: 'Change' + } + ] + } +} + +const tableData = { + utxos: { + data: [], + total: 0 + }, + payment: { + fee: 0, + txSize: 0, + tx: null, + psbtBase64: '', + psbtBase64Signed: '', + signedTx: null, + signedTxHex: null, + sentTxId: null, + + signModes: [ + { + label: 'Serial Port Device', + value: 'serial-port' + }, + { + label: 'Animated QR', + value: 'animated-qr', + disable: true + } + ], + signMode: '', + show: false, + showAdvanced: false + }, + summary: { + data: [{totalInputs: 0, totalOutputs: 0, fees: 0, change: 0}] + } +} diff --git a/static/js/utils.js b/static/js/utils.js new file mode 100644 index 0000000..946a6dd --- /dev/null +++ b/static/js/utils.js @@ -0,0 +1,210 @@ +const PSBT_BASE64_PREFIX = 'cHNidP8' + +const COMMAND_PING = '/ping' +const COMMAND_PASSWORD = '/password' +const COMMAND_PASSWORD_CLEAR = '/password-clear' +const COMMAND_ADDRESS = '/address' +const COMMAND_SEND_PSBT = '/psbt' +const COMMAND_SIGN_PSBT = '/sign' +const COMMAND_HELP = '/help' +const COMMAND_WIPE = '/wipe' +const COMMAND_SEED = '/seed' +const COMMAND_RESTORE = '/restore' +const COMMAND_CONFIRM_NEXT = '/confirm-next' +const COMMAND_CANCEL = '/cancel' +const COMMAND_XPUB = '/xpub' +const COMMAND_PAIR = '/pair' +const COMMAND_LOG = '/log' +const COMMAND_CHECK_PAIRING = '/check-pairing' + +const DEFAULT_RECEIVE_GAP_LIMIT = 20 +const PAIRING_CONTROL_TEXT = 'lnbits' + +const HWW_DEFAULT_CONFIG = Object.freeze({ + name: '', + buttonOnePin: '', + buttonTwoPin: '', + baudRate: 9600, + bufferSize: 255, + dataBits: 8, + flowControl: 'none', + parity: 'none', + stopBits: 1 +}) + +const blockTimeToDate = blockTime => + blockTime ? moment(blockTime * 1000).format('LLL') : '' + +const currentDateTime = () => moment().format('LLL') + +const sleep = ms => new Promise(r => setTimeout(r, ms)) + +const retryWithDelay = async function (fn, retryCount = 0) { + try { + await sleep(25) + // Do not return the call directly, use result. + // Otherwise the error will not be cought in this try-catch block. + const result = await fn() + return result + } catch (err) { + if (retryCount > 100) throw err + await sleep((retryCount + 1) * 1000) + return retryWithDelay(fn, retryCount + 1) + } +} + +const txSize = tx => { + // https://bitcoinops.org/en/tools/calc-size/ + // overhead size + const nVersion = 4 + const inCount = 1 + const outCount = 1 + const nlockTime = 4 + const hasSegwit = !!tx.inputs.find(inp => + ['p2wsh', 'p2wpkh', 'p2tr'].includes(inp.accountType) + ) + const segwitFlag = hasSegwit ? 0.5 : 0 + const overheadSize = nVersion + inCount + outCount + nlockTime + segwitFlag + + // inputs size + const outpoint = 36 // txId plus vout index number + const scriptSigLength = 1 + const nSequence = 4 + const inputsSize = tx.inputs.reduce((t, inp) => { + const scriptSig = + inp.accountType === 'p2pkh' ? 107 : inp.accountType === 'p2sh' ? 254 : 0 + const witnessItemCount = hasSegwit ? 0.25 : 0 + const witnessItems = + inp.accountType === 'p2wpkh' + ? 27 + : inp.accountType === 'p2wsh' + ? 63.5 + : inp.accountType === 'p2tr' + ? 16.5 + : 0 + t += + outpoint + + scriptSigLength + + nSequence + + scriptSig + + witnessItemCount + + witnessItems + return t + }, 0) + + // outputs size + const nValue = 8 + const scriptPubKeyLength = 1 + + const outputsSize = tx.outputs.reduce((t, out) => { + const type = guessAddressType(out.address) + + const scriptPubKey = + type === 'p2pkh' + ? 25 + : type === 'p2wpkh' + ? 22 + : type === 'p2sh' + ? 23 + : type === 'p2wsh' + ? 34 + : 34 // default to the largest size (p2tr included) + t += nValue + scriptPubKeyLength + scriptPubKey + return t + }, 0) + + return overheadSize + inputsSize + outputsSize +} +const guessAddressType = (a = '') => { + if (a.startsWith('1') || a.startsWith('n')) return 'p2pkh' + if (a.startsWith('3') || a.startsWith('2')) return 'p2sh' + if (a.startsWith('bc1q') || a.startsWith('tb1q')) + return a.length === 42 ? 'p2wpkh' : 'p2wsh' + if (a.startsWith('bc1p') || a.startsWith('tb1p')) return 'p2tr' +} + +const ACCOUNT_TYPES = { + p2tr: 'Taproot, BIP86, P2TR, Bech32m', + p2wpkh: 'SegWit, BIP84, P2WPKH, Bech32', + p2sh: 'BIP49, P2SH-P2WPKH, Base58', + p2pkh: 'Legacy, BIP44, P2PKH, Base58' +} + +const getAccountDescription = type => ACCOUNT_TYPES[type] || 'nonstandard' + +const readFromSerialPort = reader => { + let partialChunk + let fulliness = [] + + const readStringUntil = async (separator = '\n') => { + if (fulliness.length) return fulliness.shift().trim() + const chunks = [] + if (partialChunk) { + // leftovers from previous read + chunks.push(partialChunk) + partialChunk = undefined + } + while (true) { + const {value, done} = await reader.read() + if (value) { + const values = value.split(separator) + // found one or more separators + if (values.length > 1) { + chunks.push(values.shift()) // first element + partialChunk = values.pop() // last element + fulliness = values // full lines + return {value: chunks.join('').trim(), done: false} + } + chunks.push(value) + } + if (done) return {value: chunks.join('').trim(), done: true} + } + } + return readStringUntil +} + +function satOrBtc(val, showUnit = true, showSats = false) { + const value = showSats + ? LNbits.utils.formatSat(val) + : val == 0 + ? 0.0 + : (val / 100000000).toFixed(8) + if (!showUnit) return value + return showSats ? value + ' sat' : value + ' BTC' +} + +function loadTemplateAsync(path) { + const result = new Promise(resolve => { + const xhttp = new XMLHttpRequest() + + xhttp.onreadystatechange = function () { + if (this.readyState == 4) { + if (this.status == 200) resolve(this.responseText) + + if (this.status == 404) resolve(`

`) + } + } + + xhttp.open('GET', path, true) + xhttp.send() + }) + + return result +} + +function findAccountPathIssues(path = '') { + const p = path.split('/') + if (p[0] !== 'm') return "Path must start with 'm/'" + for (let i = 1; i < p.length; i++) { + if (p[i].endsWith('')) p[i] = p[i].substring(0, p[i].length - 1) + if (isNaN(p[i])) return `${p[i]} is not a valid value` + } +} + +function asciiToUint8Array(str) { + var chars = [] + for (var i = 0; i < str.length; ++i) { + chars.push(str.charCodeAt(i)) + } + return new Uint8Array(chars) +} diff --git a/static/qrcode-example.png b/static/qrcode-example.png deleted file mode 100644 index 29781f5361e1a8973d89c8166286448c871d9d3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10045 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 Gq5liq_H`xz diff --git a/static/qrcode-example1.png b/static/qrcode-example1.png deleted file mode 100644 index a6c748f1115ecd0cb6448d17f94456c7dad274e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34299 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�zWpdI2sh9i(36;HJ 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 diff --git a/static/quasar-framework.png b/static/quasar-framework.png deleted file mode 100644 index c06e8cfade3bdb3643d3be8754080d85f3c90b09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2084 zcmV+<2;29GP)P000>X1^@s6#OZ}&0004nX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmP!xqvQ?*hm4t5Z6$WWau6f5GWRVYG*P%E_RVDi#GXws0R zxHt-~1qXi?s}3&Cx;nTDg5VE`tBaGOilB$#OK5lCS8#Dk?Tr}-#8at7Iu?YAB-u8&TSIQY@tDJmKLVas3jx6mpfp z$gzMbG{~+W{11N5)+)p&TS=h=(EH*zA7emZ7iiWU=lj@knkRt&8Mx9r{%Ql5`6RvG z(IQ8{;5Kk^-O-di;Bp5TellcJb|pV8p-=$c&*+y{D4^000SaNLh0L z01ejw01ejxLMWSf00007bV*G`2j>9>3ojhi)_gSp00tmQL_t(Y$BkBdP*hbI|J}Ry z-h~AOcLNti1X45*K@2J;rZfmQo0?I|8OElEljuk_OvNABd!{j`DV?#I+NsPe$}BB4 zUCb9?0SWPNQ4kdpTwcO1?6SM}wdeH5;y%*Cem$|_dx)j_^ z0LI)W^oQ2GkeO$Qj|z+vLc;(6fC3=XgONHO1uIgc7iJ}Vap=3Q)qthc++gzDSgQ#I zC|oz|&$5jf@YJ^+A^04@Kh*x#)J0JJRd+7b@iRz@IuE{kt#uA$Lt zhw7sM07)jOZMS35gUJs)ur~hNu#-Gm_`;iODi)W$y?+=x+gvax3hqgrf$en?%-t%6 zBw&t~!PbYgxG#-|M#JFyu{oeOaTByX<4ugV0HK@O5lMH9u_dy;Ai)8{}kS>wFhY0)$PHq z?!XnG$)TdA!-=A`$>u?;qZk-tS-3q4 z46yKzLB73`4-5c@O3~gk8AeA-Yg<^qwXHqyt>qXzwTKHmH?k7)r0^QB zs^SX_LNcms;gliD1TK#Pt)K+}loS`ir>bae??86eVm!X;u`rMskqolq7&JR5>aO@;oWbI* z7#1#<1g6V6Ol%rG^O;pa;Vc&GmI*LKv$#_uga!oiO_PK@y?$omIG{X}M+)QcvV9lr z{o@`AhYB3B5o|ar;)qqoq?g_i$i7oUa5!cEX|zE#PN=}}6v1G>^Q>k;Tq$2pb&dWKx3^TMNg$_E@6@Zqh$WNbJg;h7^M1}B0-7`!f`>W6D^5sI%G zC*hTR2+x z8|k&VQSntDS||Npml_2SLNT2oFfW2Z(Hxo9A08+RWXbXZ3$uGi%l-@fBDGj$>Xrzl zlu}ux^sg%lHUA+}k3^`f_^73Egyz3xrHNJN=(8Vp(=%;jRFZv^Qc67%p*5W{?Yt_| zpTF+ddb`3w_tUP9TG6Y}n@v`Hw57{IH|@Mg6RXYz+KIEHx2zSt3O&5{e06z&g}o)m z`*X6TMD(a%nx0;`E;PrtT$n&9I0jHcP&fwAOvi`Uqu_koP+#rA{<7CUDs1}Sk|=~eAtgU* zb>1V!N@H?N4g^6^85Wdb079Ul1gxTZuiISBt@R@x_SCzM-CPRYuzvx{MIV*EMcR!3 O0000D_&t;q-8CgcShby-<{aNX%p-ioA1+ z5k)mhbf%$auyEw*&tZ`)8}e)r%U{;DwY%+09B#|S-wC?wSd;uQv*KHt-x2?bG00>3 zC5wiy|Ly3G#QWKA zlce|t4!q-=@XKH47!t3&l-dAm4ptLP`2}As=-C&188_13`DXJ_Y_B?~`zS^N7KDHL z%|kcex+n9|&J*otOKGR3QYS%=k_VH{mzoa7vBx7`{OIg@DkBw0UNYX*9rK2};pauZ z+1t~r1C_>oznL|=M%zF$?auox0TMqiZWA^y4SZzo&PHx;Iq$B2+Ol=%oj_$ncbV;k@gZjhe=6c5mXsIbaw89wn z?#=82l_>&dR*ifda_kq?Ju0?GDEbec;KV9L;3hQaFgK70TB|*i@+1;4@Z}QZ=1YLQ ztsOANF)3`Z&dI2@@#Pv#^btFjFqeN^Sf9UXm8|sEmULgit|YRUq>OP2QZ$?}uUw&K zXtzK^QbJZGEtgsDNelAZYrttP>$sfU87Kf`@GVSC_EWg=?O1LOHnEV8w4Ab6aA8#d zO#sx*Haa(L?0wJ|nc z+41o@ZSkQcu%j+DNA)V=`jy~{?kxqQXjb%2T=}oUT4wae43m{KH!dhcr>w^rG>+YipRSv~>l=T3L1$=IV!s) zw;DChP{QV@s2v-m+*1)9dIUEdX%mzT55H7uc^C`1y$7XyuiO?`PYU8ZIOFvX*!V2* zlP}>b_2u5^_S=Hq6eR?a0_b32w)KU)L>s(Glf%)E|3 z)ITv=aPuxrnyGM0Ar_Xd;nY*F#Z{RWWMjn>>K-m&Gs39vr_Js+Qi`-MJKr__VenWO zvNMw6dN20cVFGQQ9JTorEX{`y9kz`!F;8q?7v<)Ru-7vq;y zWPq6Pq*m-9nKeJE*+g}Pgajy z7p`yXCio#zWXGSVB4$6KM-smuBh!%Gw`G*=ee0>rJN=UNnPV>Pu6PuubB)`h8@n&= z?^-=O0G?izd5^Iy3Mix$jaD%2&8S1c#R1)~_zRa`jR8Us;=x@iGi_D^aMZF9*#ehIi;gatfjT0DYKy7HLoDv zJ-t3@IK$v*kd-Qyz7OroV!*ZP86*6$o%J}W8_Jgjv~I zoJg4MR?gLEiAHAr*#bFOpPEE%x;ZY?hs$diis*~YOm($;iCIBD7RgywaT|mXM z$^GiBVj9;EXjW8SwnfO(i)EVB&}~{iWC@;4xgMZo7=;&Nvs%EwqPNVpuWU%GeSlw4 zC25`gY@p20=fgs`x`0@7EoJJ|x6*T%7t8AAQ;!=2l6$%uN5v8so}~6Kl)B#ej?ONg z4q*R0MJ;6>OJUN@do=$F^@Y2l&IZGWDiSk$xNEd+wp#X63=T7cL)bol!WFu{6x}*1 zppo5ol78qIb|H6jrET!w>PKzv!{HWzr98hOG8 z%Wf`0bnflOr2$Jtx7uVMA^Qx5Go9qX`JDu={brr!6l8YTUNrdTb?zo^scjGkRIbi1 z*byEt*5O)QaNZ+OY%!B@&*u(G7ov!vi!%EZlV%Fw8(<$Kw8Ufn^!T8DK@s35N5QY& zZhgdur)?8Wi;X?ci<`&$?s+2LB9k~CbDp9{zU?c!M570E$ET&3qVi(7U`*VXLFEZ* zno$R*sMyhQk>_*;?}hX0`wTgw|`_x(UyZDKzh>%tXk%fC-E_Vyt zp8+QltHbm{5FhiiXUXzTT^IZ?UB-e-L|ES?gjumvoL!*#a!%mIqY;A4>QEb=T`=3F zb?#}>&|@XQOFN)^6!$+crQ&Z+8-(X_zeDHo{gM?a@%agUj*LwznyRzV)8 z{#CHT7R>4(imR}nswkPOzH8NlsB^-vX(uk!Hq;0=7o38_Xp8~ee=Qq?3^THQzt{hpil?$>*wswLV+Ksrh1 zX8a_LH#!8wOe-5WOfM_O8CL@V1OcR4E-}%E>1f;Li^+$t2Pz@5OneA+?V&6zl!2jR z$X7~Zulo_G%_C_c8Kw(%kpWgck}tU|$uM*1Usd$sV#svo5t-k^uvoyt#;C>S%Q&y= zZDY-V+|Pv;rav^)ytZjW-K5OOWx&}ZKgeuloI6)o;bX%FNhtVhOz64bmc87sBE@e# zUkjn&_v0d13ZXUUA+#aDW3b)D?vs(1pCFHw0aGQgxk)oRjy%|GHycZRnneHe)t&a9 z%~2e!w8UI7dzqIcqz&_VdV8$~0h*=US^)?X$HqWPqIuV<933x%K#4NSbOm&gC$=Zm z8H(}&Ya$!4=nf^uM)Q&H{qY<&H7IOjk1>6GFRvKwq@O0+6Wz<&jeO0UD_|m+Dl!U%IQPYys(gJRY3 zd@z@3AC;oqMyoM6j{OrGcIlWM*6kpK{&Q}3R+b)RLU*tnATsPaK0vr>Msee?%?Fd_ zQlA{`4^E(e;&CHNpQt^j*AkOASn87@bTfFb5}&E(9&6z|7JY^heO6>e`)<{ig7sJL z?>uT_BxJ)qQfsuDZ|bQ#B3}|WeH&0^-rs)omX2bb$`I87ch7-bye| zSS0t`U^JvWS+%ebvi1YM5F24opB;aPo)LuK(*O`UUb^)Z*ZGbH(EI`bKF{csQ_TIL zwf=5OE191Y!!W8o^#=7@Sa{FwJsAb6wL`@SoU%AlX?BeX71pa51SJ=HjxurhglDED zib7NryT}8>2`{OQ_2Z`>m#IdTvG6XzBXSV}AV9@pV-8iDhrX$enmby#ZEI;tjDOE@ zlGlar%kAYoa_%h$m;2hxeK^JFpD5hleq8Dk^p81sc&Km)F}CK{&q(DgJ@s@k9l(At zMrsghJ0K*8rwPTv-;!D6Q5F}5R-H_BduWBJe2FFIqKLxDvFTO4oy?DRQcWxPS^Pzl zVmzpVan^uhYqPUkT}lQvqdr=W|FOepq>acIT`HSb`q6R366@^NWC=d~F^zpuoK*6ZW93Tmf#g1`-6l)(Bf zfK!lSGU&k&!K6q&<2w%TWXmU^n8rgx#^J(FilLZ*w*iItSPtwj)O$y3P3wc(G$QAx z(H)6!ai>+oo=*aES*Pf>-@(=lGVjc#>OQ8hV$iTrw|1(VlYrrlU-;ccOzNWVkAOW! zJ%blw2?q!K4(dEgtxYBORH^$Rhrt-Wq!Us$8j{I*Xlqr*E+}veNt7P5I??GG);Y9J z(G76ecgnDSnUhNoh=m%R0koELPoOmOu{o_B+SBhf8P+L_rcox{A)N~0oIj!_SI8mG zvC4rF)u?p(O;87t={@JUrW)!E4);X%*`5bl>UHLVk$W(gTB^>eoCgssAG!;uDyjcI_k3)9@3^u%i%t9#rYYB zcHiBlK7{YY{qZ%`R6!e2)ib7LE)N7IC|R>r2bToR9h+3Nh^(_ppI*|})t~8n_oe$% z9G{uTTocCqV(&Ap7#jv}n_1_*%RMx4oWv>3dGF;oi~I=u^or+WqABKC)2>CG$62Tb7mq+&SO11 zVHP{@XCh^?*}*(EcE+o&a>fE=lHLXT=9(1cYm8JN(qop+!%njZl4`^7tG^U?BN zIP@Y0yU>PvF~ZDzAZ*Glxa6M2s&`Z9H!Q{0Y-$r@bY+|!ZLz8^GqQEpuWMTa6SuN; z4d$ivYY+0q9J%<}^rjrT-CmrBMA0lfXC_zP5L=TUh#y-zqsz)tPy$M_&yARFveaX41;9&y7kkit# z^U%&d=Q6*ec=r59&wf7L5Bs4PW(Za75TW}#b_CQ0;ryuLTyWKs7WGEurrh$}SDQE` zXi9VCHXLc0J5{3;F7J|rh# z>{9*+8d02hyas(7u9Rm_AKW&%(`M-g1(&LM=h@$9AfgD9k+PYHE$*h&^@o-6%i>K? zWGXb;`lx;=p4=Tup+X%#3H04^pSE!7Z#`J+%GJS@+;ZR&4)X=~p4z@yAU9<(yWAgh zqqdAT{`upMJd?GcdZ3IR=fxC0_4Dqge2y{9!9J-4khC95B$3IPZT~K9ax2G1psN?} zy~wNd8m#qcG~)8Ihmy1?eqj&I%5lPGOtN)WnacgXZ!CbHpimlpe8+lMb_$=zhWA52^bk_Do(hoQ2IwFW~;!MosyX0kzAsUwy*(kE{1^>4l zFNCu@>{rJN93zb%EQNXRsJ({;AoqU9eh%z?wt5F!hAav=P;9mzCc@ce64qQGv$;Vn zhGnoFRgvTnFN!)fZRUIExzI-rJwumUVuSZm1jyXvef*vwdu|a3Sy@dbS=oQI*pOzj z0$zd@do@WSG@djt0`WZ`xD05T)U&d$m+G?0L}+r<@0*`aN!m;$6gG=szd^$YBCEjX z8fyhLV~4I1L|4Qn<;Ny_n;F^=ZbbCoh#bA{^}9rosp=D`fYD62FRFfkS%B);(M{K6 z$z>>dqenPl>WM_hmDPUx#jUZYoJXCK9EDau^zV>$1FLkQ6ZDhwVh86H7W}%k4l;@B%loybM-fLHSd%Sn!EsuY~j#(n(e0y<YWS*6;9!n5?Kpm*O?Hnj(I?=$tI4o%Rv1s+R& z2ODt+i%u$He+V8U@4uozMQxMn*cbWS|NMz0%8&7PDJ!RGcJD@5_GVJaL{WX4LSnz9 z79XIbiAmihF=W2wxI$pH&>RQKe@;fZb_{vl@L?%qMJ20cZnkK!hlPjEFfJ=aj2Po%_@Z@8Zz@`^> zwX_0hL*)O2K;D5FZQR|RLEPM4US3>Y{9I11*4(_JqN3b9eB69|K%@lF&BxIl>J4;s zWBLX02L=T026IK$Gs4M{{ud_H!pXxO%*cqGr~ik44$f+7|AcpR`;!GEAKczhXKr3D z9&QH*?!RidxyyMXLH=~;-)gw&AX~@W+Hf}~4_6pm&J*tF&h%FZOV~g4ojqLbe}`iU z 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 diff --git a/static/script-example.png b/static/script-example.png deleted file mode 100644 index 813a4254fd77e230e3c3a9375481ad3cace02a40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95823 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 diff --git a/static/vif-example.png b/static/vif-example.png deleted file mode 100644 index 3e6cfa11ed2fecad86f5e909ce7b342d8296e09b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22515 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 diff --git a/static/vuejs-framework.png b/static/vuejs-framework.png deleted file mode 100644 index eb634533cedbe461c6e4a6505a04b4a9dd013d38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1099 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 B66pW{ diff --git a/tasks.py b/tasks.py deleted file mode 100644 index 8440644..0000000 --- a/tasks.py +++ /dev/null @@ -1,25 +0,0 @@ -# tasks.py is for asynchronous when invoices get paid - -# add your dependencies here - -import asyncio - -from lnbits.core.models import Payment -from lnbits.tasks import register_invoice_listener -from loguru import logger - - -async def wait_for_paid_invoices(): - invoice_queue = asyncio.Queue() - register_invoice_listener(invoice_queue, "ext_example") - - while True: - payment = await invoice_queue.get() - await on_invoice_paid(payment) - - -async def on_invoice_paid(payment: Payment) -> None: - # Will grab any payment with the tag "example" - if payment.extra.get("tag") == "example": - logger.info("example extension received payment") - logger.debug(payment) diff --git a/templates/example/index.html b/templates/example/index.html deleted file mode 100644 index 6c6d094..0000000 --- a/templates/example/index.html +++ /dev/null @@ -1,442 +0,0 @@ -{% extends "base.html" %} {% from "macros.jinja" import window_vars with context -%} {% block scripts %} {{ window_vars(user) }} - - -{% endblock %} {% block page %} - - - - - - -
- Update thing - Create thing - Cancel -
-
-
-
- - - -
- - - - - - - - - - - - - - - -
Frameworks
- - - - FASTAPI - - QUASAR - - VUE-JS - - - - - - -

- LNbits API is built using - FastAPI, a high-performance, easy to code API framework.

- FastAPI auto-generates swagger UI docs for testing endpoints - /docs -

- - - TIP: Although it is possible for extensions to - use other extensions API endpoints (such as with the Satspay and - Onchain extension), ideally an extension should only use LNbits - core - endpoints.

- - views.py is used for - setting application routes: -

- views_api.py is used for - setting application API endpoints:
- -
- - -

- LNbits uses - Quasar Framework - for frontend deisgn elements. Quasar Framework is an open-source - Vue.js based framework for building apps. -

- - - TIP: Look through - /template files in - other extensions for examples of Quasar elements being used.

- -

- In the below example we make a dialogue popup box (box can be - triggered - here): Exmple of a tooltip! -

-

-
Useful links:
- Style (typography, spacing, etc) - Genral components (cards, buttons, popup dialogs, etc) - Layouts (rows/columns, flexbox) -
- - - - -

- LNbits uses - Vue - for best-in-class, responsive and high-performance components. -

- -

Typical example of Vue components in a frontend script:

-

- -

- Content can be conditionally rendered using Vue's - v-if: -

- -
-
-
- - -
Useful Tools
-
- - MAGICAL G - EXCHANGE RATES - QR CODES - WEBSOCKETS - - - -
Magical G
-

- A magical "g" (ie - this.g.user.wallets[0].inkey) is always available, with info about the user, wallets and - extensions: -

- {% raw %}{{ g }}{% endraw %} -
- -
Exchange rates
-

- LNbits includes a handy - exchange rate function, that streams rates from 6 different sources. -

- Exchange rate API:
-

- Exchange rate functions, included using - from lnbits.utils.exchange_rates import - fiat_amount_as_satoshis:
- -
- -
QR Codes
-

For most purposes use Quasar's inbuilt VueQrcode library:

- -

- LNbits does also include a handy - - QR code enpoint -

- {% raw %} You can use via - {{protocol + location}}{% endraw - %}/api/v1/qrcode/some-data-you-want-in-a-qrcode:
-
- -
- - -
-
- - -
Websockets
-

- Fastapi includes a great - websocket tool -

- {% raw %} -

- A few LNbits extensions also make use of a weird and useful - websocket/GET tool built into LNbits, such as extensions - Copilot and LNURLDevices
- You can subscribe to websocket with - wss:{{location}}/api/v1/ws/{SOME-ID}
- You can post to any clients subscribed to the endpoint with - {{protocol + - location}}/api/v1/ws/{SOME-ID}/{THE-DATA-YOU-WANT-TO-POST}
-
-

- DEMO: Hit - {{protocol + - location}}/api/v1/ws/32872r23g29/blah%20blah%20blah - in a different browser window to change this text to `blah - blah blah`. -
-
- Function used in this demo:
-

- - {% endraw %} -
-
-
- -
Useful links
- - - - - - - LNbits GitHub Repository - - Includes the LNbits repo and other useful repositories like - lnbits-extensions for submitting extensions - and many LNbits-related projects. - - - - - - - - - - LNbits YouTube Channel - - Features useful tutorials and updates, including how to build - your own extension. - - - - - - - - - - Makerbits YouTube Channel - - Offers great hardware tutorials for projects that integrate - with LNbits. - - - - -
- - -
Good Practice
- Coming soon... -
- - -
Dev Enviroment
- Coming soon... -
- - - -
-
-
-
- - -{% endblock %} diff --git a/templates/silnt/_api_docs.html b/templates/silnt/_api_docs.html new file mode 100644 index 0000000..1af6fd9 --- /dev/null +++ b/templates/silnt/_api_docs.html @@ -0,0 +1,266 @@ + + +

+ + Silnt
+ + Created by: + Ponthief + +
+ Usage
+ + 1. Add Nostr Account - private key ('Nsec')
+ 2. Add Nostr Relay(s) for Account to connect to
+ 3. Add existing BOLTCARD:
+ - enter card's UID
+ - enter Nostr 'npub' of the user who owns the card
+ - enter card Name to use when issuing commands via Nostr
+ +
+

+
+
+ + + + + + + GET /cardanostra/api/v1/accounts +
Headers
+ {"X-Api-Key": <admin_key>}
+
Body (application/json)
+
+ Returns 200 OK (application/json) +
+ [<account_object>, ...] +
Curl example
+ curl -X GET {{ request.base_url }}cardanostra/api/v1/accounts -H + "X-Api-Key: <admin_key>" + +
+
+
+ + + + + GET /cardanostra/api/v1/relays +
Headers
+ {"X-Api-Key": <admin_key>}
+
Body (application/json)
+
+ Returns 200 OK (application/json) +
+ [<relay_object>, ...] +
Curl example
+ curl -X GET {{ request.base_url }}cardanostra/api/v1/relays -H + "X-Api-Key: <admin_key>" + +
+
+
+ + + + + POST /cardanostra/api/v1/account +
Headers
+ {"X-Api-Key": <admin_key>}
+
Body (application/json)
+
+ Returns 200 OK (application/json) +
+ {account_object} +
Curl example
+ curl -X POST {{ request.base_url }}cardanostra/api/v1/account -H + "X-Api-Key: <admin_key>" + +
+
+
+ + + + + POST + /cardanostra/api/v1/relay +
Headers
+ {"X-Api-Key": <admin_key>}
+
Body (application/json)
+
+ Returns 200 OK (application/json) +
+ {relay_object} +
Curl example
+ curl -X POST {{ request.base_url + }}cardanostra/api/v1/relay -H "X-Api-Key: + <admin_key>" + +
+
+
+ + + + + POST + /cardanostra/api/v1/register +
Headers
+
Body (application/json)
+
+ Returns 200 OK (application/json) +
+ {card_object} +
Curl example
+ curl -X POST {{ request.base_url + }}cardanostra/api/v1/register -H "X-Api-Key: + <admin_key>" + +
+
+
+ + + + + DELETE + /cardanostra/api/v1/accounts/{id} +
Headers
+
Body (application/json)
+
+ Returns 200 OK (application/json) +
+
Curl example
+ curl -X DELETE {{ request.base_url + }}cardanostra/api/v1/accounts/{id} -H + "X-Api-Key: <admin_key>" + +
+
+
+ + + + DELETE + /cardanostra/api/v1/relays/{id} +
Headers
+
Body (application/json)
+
+ Returns 200 OK (application/json) +
+
Curl example
+ curl -X DELETE {{ request.base_url + }}cardanostra/api/v1/relays/{id} -H + "X-Api-Key: <admin_key>" + +
+
+
+ + + + DELETE + /cardanostra/api/v1/cards/{id} +
Headers
+
Body (application/json)
+
+ Returns 200 OK (application/json) +
+
Curl example
+ curl -X DELETE {{ request.base_url + }}cardanostra/api/v1/cards/{card_uid} -H + "X-Api-Key: <admin_key>" + +
+
+
+ + + + PUT + /cardanostra/api/v1/restart +
Headers
+
Body (application/json)
+
+ Returns 200 OK (application/json) +
+
Curl example
+ curl -X PUT {{ request.base_url + }}cardanostra/api/v1/restart -H + "X-Api-Key: <admin_key>" + +
+
+
+
\ No newline at end of file diff --git a/templates/silnt/components/address-list.html b/templates/silnt/components/address-list.html new file mode 100644 index 0000000..25498fb --- /dev/null +++ b/templates/silnt/components/address-list.html @@ -0,0 +1,215 @@ +
+
+
+ +
+
+ +
+
+ + + +
+
+ + + +
diff --git a/templates/silnt/components/fee-rate.html b/templates/silnt/components/fee-rate.html new file mode 100644 index 0000000..e337da9 --- /dev/null +++ b/templates/silnt/components/fee-rate.html @@ -0,0 +1,62 @@ +
+
+
Fee Rate:
+
+ +
+
+ +
+
+
+
+
+ + Warning! The fee is too low. The transaction might take a long time to + confirm. + + + Warning! The fee is too high. You might be overpaying for this + transaction. + +
+
+ +
+
Fee:
+
${feeValue} sats
+
+ Refresh Fee Rates +
+
+
diff --git a/templates/silnt/components/history.html b/templates/silnt/components/history.html new file mode 100644 index 0000000..40adbcb --- /dev/null +++ b/templates/silnt/components/history.html @@ -0,0 +1,144 @@ +
+
+
+
+ + + +
+
+ + + + + Export to CSV + + + + +
+
+ + + +
diff --git a/templates/silnt/components/my-checkbox.html b/templates/silnt/components/my-checkbox.html new file mode 100644 index 0000000..0f76b6d --- /dev/null +++ b/templates/silnt/components/my-checkbox.html @@ -0,0 +1,5 @@ +
+
+
${ title }
+ XXX +
diff --git a/templates/silnt/components/payment.html b/templates/silnt/components/payment.html new file mode 100644 index 0000000..bd43469 --- /dev/null +++ b/templates/silnt/components/payment.html @@ -0,0 +1,310 @@ +
+ + + + + + + + + +
+
+ +
+ +
+
+ Fee Rate: + ${feeRate} sats/vbyte + Fee: + ${satBtc(feeValue)} +
+
+
+ +
+
+ + +
+
+
+
+ + + +
+
+ +
+ +
+
+ Balance: + ${satBtc(balance)} + Selected: + + ${satBtc(selectedAmount)} + +
+
+
+ +
+
+ + +
+
+
+
+ + + +
+
+ +
+ +
+ + Below dust limit. Will be used as fee. + +
+
+
+ Change: + + ${satBtc(0)} + + + ${satBtc(changeAmount)} + +
+
+
+ +
+
+ +
+
Change Account:
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+ + + + + Serial Port + + Sign using a Serial Port device + + + + + Share PSBT + Share the PSBT as text or Animated QR Code + + + + +
+ +
+ + + The payed amount is higher than the selected amount! + +
+
+
+ + + + +
+ Close +
+
+
+ + + +
+
+ Transaction Details +
+
+ +
+
+
+
Version
+
${signedTx.version}
+
+
+
Locktime
+
${signedTx.locktime}
+
+
+
Fee
+
+ ${satBtc(signedTx.fee)} +
+
+ + Outputs + +
+
+ ${satBtc(out.amount)} +
+ +
+ ${out.address} +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+ Send + Close +
+
+
+
diff --git a/templates/silnt/components/seed-input.html b/templates/silnt/components/seed-input.html new file mode 100644 index 0000000..6203880 --- /dev/null +++ b/templates/silnt/components/seed-input.html @@ -0,0 +1,80 @@ +
+
+
+
Seed Input Done
+
+
+
+
+
Word Count
+
+ +
+
+
+
+
+
Enter word at position: ${actualPosition}
+
+
+
+
+ Previous +
+
+ +
+ +
+ Next + Done +
+ +
+
+
diff --git a/templates/silnt/components/send-to.html b/templates/silnt/components/send-to.html new file mode 100644 index 0000000..ecaa580 --- /dev/null +++ b/templates/silnt/components/send-to.html @@ -0,0 +1,77 @@ +
+
+ + + +
+
+ Add +
+
+
+ Payed Amount: + + ${satBtc(getTotalPaymentAmount())} + +
+
+
+
+
diff --git a/templates/silnt/components/utxo-list.html b/templates/silnt/components/utxo-list.html new file mode 100644 index 0000000..1ae3aea --- /dev/null +++ b/templates/silnt/components/utxo-list.html @@ -0,0 +1,142 @@ + + +
+
+ +
+
+ +
+
+
+
+ + + +
+
+ + + +
diff --git a/templates/silnt/components/wallet-config.html b/templates/silnt/components/wallet-config.html new file mode 100644 index 0000000..66abe35 --- /dev/null +++ b/templates/silnt/components/wallet-config.html @@ -0,0 +1,49 @@ +
+ +
+
+ + +
+
+
+
${satBtc(total)}
+
+
+
+
+ + + + + + + + +
+ Update + Cancel +
+
+
+
+
diff --git a/templates/silnt/components/wallet-list.html b/templates/silnt/components/wallet-list.html new file mode 100644 index 0000000..f1e562f --- /dev/null +++ b/templates/silnt/components/wallet-list.html @@ -0,0 +1,214 @@ + + +
+
+ + + + + New Wallet Account + Generate Silent Payment Address + + + + +
+
+
+ + + + +
+
+ + + + + + + Encrypted and not stored anywhere + + + + Block Height of the First Transaction + + + + Email format - see BIP353 + + +
+ + + + Cancel +
+
+
+
+ + + + + + + Block Height of the First Transaction + + + +
+ + + + Cancel +
+
+
+
diff --git a/templates/silnt/index.html b/templates/silnt/index.html new file mode 100644 index 0000000..303451c --- /dev/null +++ b/templates/silnt/index.html @@ -0,0 +1,326 @@ +{% extends "base.html" %} {% from "macros.jinja" import window_vars with context +%} {% block page %} +
+
+ + + + + + + +
+
+ Scan Blockchain +
+
+ +
+
+ + + + + New Payment + Create a new payment by selecting Inputs and + Outputs + + + + + From Signed Tnx + Paste a signed Transaction + + + + + + Back +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + +
+ Silent Payments Wallet Extension + (v0.1) +
+
+ + + {% include "silnt/_api_docs.html" %} + +
+
+ + +
Address Details
+
+ + + + +

+ + + +

+

+ +

+
+ Gap limit of 20 addresses exceeded. Other wallets might not detect + funds at this address. +
+
+ Save Note + Close +
+
+
+
+ + + +
Enter the Signed PSBT
+
+ +

+ +

+ +
+ Check PSBT + Close +
+
+
+
+
+ +{% endblock %} {% block vue_templates %} + + + + + + + + + + + +{% endblock %} {% block scripts %} {{ window_vars(user) }} + + + + + + + --> + + + + + + + + + + + + + + + + + +{% endblock %} diff --git a/uv.lock b/uv.lock index 7d4cf50..2b3a169 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,10 @@ version = 1 revision = 3 requires-python = ">=3.10, <3.13" +resolution-markers = [ + "python_full_version >= '3.11'", + "python_full_version < '3.11'", +] [[package]] name = "aiohappyeyeballs" @@ -299,6 +303,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d6/7c/8313d981d66f2ff20e8277c1b410ecd1a12354726ce0890956ad0f278451/bitarray-3.7.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ac56caf0d0d00815444d18560d97ae3f1130e14e250438b02354c7cdcaa6eec3", size = 146881, upload-time = "2025-08-24T18:54:47.923Z" }, ] +[[package]] +name = "bitcoinlib" +version = "0.6.12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ecdsa", marker = "sys_platform == 'win32'" }, + { name = "fastecdsa", marker = "sys_platform != 'win32'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pycryptodome" }, + { name = "requests" }, + { name = "sqlalchemy" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/6e/eb8c570b06662984b0860b5cbddde63172b73c259c78b8281a1dc9d85b54/bitcoinlib-0.6.12.1-py3-none-any.whl", hash = "sha256:ed4ba895021004f448103378202dba55d3c24b3fc04848e4135aa712bc1ea971", size = 4251750, upload-time = "2023-11-23T21:54:59.846Z" }, +] + [[package]] name = "bitstring" version = "4.3.1" @@ -644,7 +665,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -681,6 +702,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6e/03/70ca13994f5569d343a9f99dba2930c8ae3471171f161b8887d44b6c526f/fastapi_sso-0.18.0-py3-none-any.whl", hash = "sha256:727754ad770b70690f1471f7b0a9e17c6dfd8ebd6e477616d3bde1eaf62e53dc", size = 26103, upload-time = "2025-03-20T17:09:08.656Z" }, ] +[[package]] +name = "fastecdsa" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/88/3a4a4c4b6143fe0e4c20fe4b5bb0142e6fa5f2d8763710b1f3d7dff9d5e3/fastecdsa-3.0.1.tar.gz", hash = "sha256:f4b4a50fd5e346c4949aba365c061c3f6b25eee7983c973e1d31de7672ba48ea", size = 47583, upload-time = "2025-01-28T00:23:25.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/7c/d7d224daabf5b00eb1ca154b90fa73f3a46f292df1af636338c7039c2c35/fastecdsa-3.0.1-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:5793ac17891bc8c7002c8364b5df32ac17b486a68c6e32d941f3f0b3641b417b", size = 274247, upload-time = "2025-01-28T00:22:43.378Z" }, + { url = "https://files.pythonhosted.org/packages/d5/d1/641baf79b39671488b2f0141b80ef816a5c8bf5128d469da1dd9b729108b/fastecdsa-3.0.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:e99b2695f3cbf363fa4fc12e036b5a2b50a01004b82972dce102bb73fa1833bd", size = 254798, upload-time = "2025-01-28T00:22:45.618Z" }, + { url = "https://files.pythonhosted.org/packages/78/1c/f37f8afb09f32ce7874b312dfa5098a2b4963e40ed094c46b4d939677d8e/fastecdsa-3.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c730285951bd3dce40ff6ba0527847864d4fc63145c8479d5245e5544de4ee8", size = 287528, upload-time = "2025-01-28T00:22:48.165Z" }, + { url = "https://files.pythonhosted.org/packages/9b/b7/de7e1789c3a7e97dedffa01a61868669d4aff5500e71bf71f220473212ac/fastecdsa-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb11b805f0c9c4e6b8eb8766b7eeaf9b7e425ff2f17eed08a402568e0548734d", size = 302619, upload-time = "2025-01-28T00:22:50.8Z" }, + { url = "https://files.pythonhosted.org/packages/2b/88/edc752ef1b0f4cd2de95b055037a6e86b9fe9a548cd85543f772ad99a17f/fastecdsa-3.0.1-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:dad6e7dc1048f538e8de8d9abfabf6198b34be4cb03f1f7919c6386e9412bdde", size = 274243, upload-time = "2025-01-28T00:22:52.535Z" }, + { url = "https://files.pythonhosted.org/packages/14/29/41529815d1d40e477b386005bc0f1f731b534568f869b946e7507042baab/fastecdsa-3.0.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:5ea3e874316689d4101edd3527056a07f3c6f4d684142368f1f062dda174022a", size = 254796, upload-time = "2025-01-28T00:22:54.28Z" }, + { url = "https://files.pythonhosted.org/packages/1a/f5/a5cef9a6d1f30f5c8a08a02e2c0fe8494dadc3a75a1dd73fa6919065e527/fastecdsa-3.0.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9537ec297a899c2cfbd9cf596bac73a8677d15cddca19487edf2be47145ec6d1", size = 287529, upload-time = "2025-01-28T00:22:56.255Z" }, + { url = "https://files.pythonhosted.org/packages/8f/df/90859d232fa4b8a075c706684f4fc0f8e108384677d60fd82b87b91bdfb5/fastecdsa-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cacb1a0486ed62d09ec2eb4cb6c97910956c9dc6f9af220e1632b35cf2e6fcd7", size = 302620, upload-time = "2025-01-28T00:22:58.684Z" }, + { url = "https://files.pythonhosted.org/packages/a3/f1/37413a26a8b664b53d959c5744064b7b95a67721f926ddd3c4d77e743429/fastecdsa-3.0.1-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:2dab30e3eceb773244baadb6dbc8977f0a28741e8d2ea790f529cc1f8419b265", size = 274252, upload-time = "2025-01-28T00:23:01.466Z" }, + { url = "https://files.pythonhosted.org/packages/16/ba/647a3d2ce818738e6ff1f107f1a7c662696d13e205ce3ad4ee591e596e61/fastecdsa-3.0.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:82272ca3c91e20433e0ca66c2d96f4d4997850846586f9ff7a9533a5c3f6e253", size = 254797, upload-time = "2025-01-28T00:23:03.283Z" }, + { url = "https://files.pythonhosted.org/packages/97/73/22afe3500d674d817ce5f0ec51e043965076503fced6af3468a869a9e8c3/fastecdsa-3.0.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f16d79411ea8a3cb467da53b75e10d66db3a0f716e4d56a9d7e77e5f3ad9f71", size = 287534, upload-time = "2025-01-28T00:23:05.085Z" }, + { url = "https://files.pythonhosted.org/packages/09/51/f0a03480d932c487587d3effd34c9481d279f624d4b303af91932a4b5216/fastecdsa-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abeb065ce8fb3b2765ac7a1f7d693d5785e584629ff83ad271c02c1d55789bb1", size = 302623, upload-time = "2025-01-28T00:23:07.734Z" }, +] + [[package]] name = "filelock" version = "3.19.1" @@ -773,6 +814,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/91/ae2eb6b7979e2f9b035a9f612cf70f1bf54aad4e1d125129bef1eae96f19/greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d", size = 584358, upload-time = "2025-08-07T13:18:23.708Z" }, { url = "https://files.pythonhosted.org/packages/f7/85/433de0c9c0252b22b16d413c9407e6cb3b41df7389afc366ca204dbc1393/greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5", size = 1113550, upload-time = "2025-08-07T13:42:37.467Z" }, { url = "https://files.pythonhosted.org/packages/a1/8d/88f3ebd2bc96bf7747093696f4335a0a8a4c5acfcf1b757717c0d2474ba3/greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f", size = 1137126, upload-time = "2025-08-07T13:18:20.239Z" }, + { url = "https://files.pythonhosted.org/packages/f1/29/74242b7d72385e29bcc5563fba67dad94943d7cd03552bac320d597f29b2/greenlet-3.2.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f47617f698838ba98f4ff4189aef02e7343952df3a615f847bb575c3feb177a7", size = 1544904, upload-time = "2025-11-04T12:42:04.763Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e2/1572b8eeab0f77df5f6729d6ab6b141e4a84ee8eb9bc8c1e7918f94eda6d/greenlet-3.2.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:af41be48a4f60429d5cad9d22175217805098a9ef7c40bfef44f7669fb9d74d8", size = 1611228, upload-time = "2025-11-04T12:42:08.423Z" }, { url = "https://files.pythonhosted.org/packages/d6/6f/b60b0291d9623c496638c582297ead61f43c4b72eef5e9c926ef4565ec13/greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c", size = 298654, upload-time = "2025-08-07T13:50:00.469Z" }, { url = "https://files.pythonhosted.org/packages/a4/de/f28ced0a67749cac23fecb02b694f6473f47686dff6afaa211d186e2ef9c/greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2", size = 272305, upload-time = "2025-08-07T13:15:41.288Z" }, { url = "https://files.pythonhosted.org/packages/09/16/2c3792cba130000bf2a31c5272999113f4764fd9d874fb257ff588ac779a/greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246", size = 632472, upload-time = "2025-08-07T13:42:55.044Z" }, @@ -782,6 +825,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1f/8e/abdd3f14d735b2929290a018ecf133c901be4874b858dd1c604b9319f064/greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8", size = 587684, upload-time = "2025-08-07T13:18:25.164Z" }, { url = "https://files.pythonhosted.org/packages/5d/65/deb2a69c3e5996439b0176f6651e0052542bb6c8f8ec2e3fba97c9768805/greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52", size = 1116647, upload-time = "2025-08-07T13:42:38.655Z" }, { url = "https://files.pythonhosted.org/packages/3f/cc/b07000438a29ac5cfb2194bfc128151d52f333cee74dd7dfe3fb733fc16c/greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa", size = 1142073, upload-time = "2025-08-07T13:18:21.737Z" }, + { url = "https://files.pythonhosted.org/packages/67/24/28a5b2fa42d12b3d7e5614145f0bd89714c34c08be6aabe39c14dd52db34/greenlet-3.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c9c6de1940a7d828635fbd254d69db79e54619f165ee7ce32fda763a9cb6a58c", size = 1548385, upload-time = "2025-11-04T12:42:11.067Z" }, + { url = "https://files.pythonhosted.org/packages/6a/05/03f2f0bdd0b0ff9a4f7b99333d57b53a7709c27723ec8123056b084e69cd/greenlet-3.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03c5136e7be905045160b1b9fdca93dd6727b180feeafda6818e6496434ed8c5", size = 1613329, upload-time = "2025-11-04T12:42:12.928Z" }, { url = "https://files.pythonhosted.org/packages/d8/0f/30aef242fcab550b0b3520b8e3561156857c94288f0332a79928c31a52cf/greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9", size = 299100, upload-time = "2025-08-07T13:44:12.287Z" }, { url = "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", size = 274079, upload-time = "2025-08-07T13:15:45.033Z" }, { url = "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", size = 640997, upload-time = "2025-08-07T13:42:56.234Z" }, @@ -791,6 +836,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", size = 607586, upload-time = "2025-08-07T13:18:28.544Z" }, { url = "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", size = 1123281, upload-time = "2025-08-07T13:42:39.858Z" }, { url = "https://files.pythonhosted.org/packages/3f/c7/12381b18e21aef2c6bd3a636da1088b888b97b7a0362fac2e4de92405f97/greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f", size = 1151142, upload-time = "2025-08-07T13:18:22.981Z" }, + { url = "https://files.pythonhosted.org/packages/27/45/80935968b53cfd3f33cf99ea5f08227f2646e044568c9b1555b58ffd61c2/greenlet-3.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee7a6ec486883397d70eec05059353b8e83eca9168b9f3f9a361971e77e0bcd0", size = 1564846, upload-time = "2025-11-04T12:42:15.191Z" }, + { url = "https://files.pythonhosted.org/packages/69/02/b7c30e5e04752cb4db6202a3858b149c0710e5453b71a3b2aec5d78a1aab/greenlet-3.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:326d234cbf337c9c3def0676412eb7040a35a768efc92504b947b3e9cfc7543d", size = 1633814, upload-time = "2025-11-04T12:42:17.175Z" }, { url = "https://files.pythonhosted.org/packages/e9/08/b0814846b79399e585f974bbeebf5580fbe59e258ea7be64d9dfb253c84f/greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02", size = 299899, upload-time = "2025-08-07T13:38:53.448Z" }, ] @@ -1002,37 +1049,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/be/24966f6bb3a9c62cfda0a22521d458c5b0fe85e17f39e40389bafedae3ca/lnbits-1.2.1-py3-none-any.whl", hash = "sha256:64d5b8dc0fe5b72f811e13ada1677b09f55f1070d3da901dc26102f47a07563b", size = 3213306, upload-time = "2025-07-11T10:41:20.773Z" }, ] -[[package]] -name = "lnbits-example" -version = "0.0.0" -source = { virtual = "." } -dependencies = [ - { name = "lnbits" }, -] - -[package.dev-dependencies] -dev = [ - { name = "black" }, - { name = "mypy" }, - { name = "pre-commit" }, - { name = "pytest" }, - { name = "pytest-asyncio" }, - { name = "ruff" }, -] - -[package.metadata] -requires-dist = [{ name = "lnbits", specifier = ">1" }] - -[package.metadata.requires-dev] -dev = [ - { name = "black" }, - { name = "mypy" }, - { name = "pre-commit" }, - { name = "pytest" }, - { name = "pytest-asyncio" }, - { name = "ruff" }, -] - [[package]] name = "lnurl" version = "0.5.3" @@ -1271,6 +1287,91 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bc/0f/f704d328499458434b45c54ef88bdfee803366e0c9ef32f3377e2f396921/nostr_sdk-0.42.1-cp39-abi3-win_arm64.whl", hash = "sha256:802c74f903b120b74bf501bf68c81d5ee1dc9f7f57801a53a507044a14b9a840", size = 3303179, upload-time = "2025-05-26T09:09:09.122Z" }, ] +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, + { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, + { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, + { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, + { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, + { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, + { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, + { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, + { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, + { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, + { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, + { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, + { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, + { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, + { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/57/fd/0005efbd0af48e55eb3c7208af93f2862d4b1a56cd78e84309a2d959208d/numpy-2.4.2.tar.gz", hash = "sha256:659a6107e31a83c4e33f763942275fd278b21d095094044eb35569e86a21ddae", size = 20723651, upload-time = "2026-01-31T23:13:10.135Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/44/71852273146957899753e69986246d6a176061ea183407e95418c2aa4d9a/numpy-2.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7e88598032542bd49af7c4747541422884219056c268823ef6e5e89851c8825", size = 16955478, upload-time = "2026-01-31T23:10:25.623Z" }, + { url = "https://files.pythonhosted.org/packages/74/41/5d17d4058bd0cd96bcbd4d9ff0fb2e21f52702aab9a72e4a594efa18692f/numpy-2.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7edc794af8b36ca37ef5fcb5e0d128c7e0595c7b96a2318d1badb6fcd8ee86b1", size = 14965467, upload-time = "2026-01-31T23:10:28.186Z" }, + { url = "https://files.pythonhosted.org/packages/49/48/fb1ce8136c19452ed15f033f8aee91d5defe515094e330ce368a0647846f/numpy-2.4.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6e9f61981ace1360e42737e2bae58b27bf28a1b27e781721047d84bd754d32e7", size = 5475172, upload-time = "2026-01-31T23:10:30.848Z" }, + { url = "https://files.pythonhosted.org/packages/40/a9/3feb49f17bbd1300dd2570432961f5c8a4ffeff1db6f02c7273bd020a4c9/numpy-2.4.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cb7bbb88aa74908950d979eeaa24dbdf1a865e3c7e45ff0121d8f70387b55f73", size = 6805145, upload-time = "2026-01-31T23:10:32.352Z" }, + { url = "https://files.pythonhosted.org/packages/3f/39/fdf35cbd6d6e2fcad42fcf85ac04a85a0d0fbfbf34b30721c98d602fd70a/numpy-2.4.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f069069931240b3fc703f1e23df63443dbd6390614c8c44a87d96cd0ec81eb1", size = 15966084, upload-time = "2026-01-31T23:10:34.502Z" }, + { url = "https://files.pythonhosted.org/packages/1b/46/6fa4ea94f1ddf969b2ee941290cca6f1bfac92b53c76ae5f44afe17ceb69/numpy-2.4.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c02ef4401a506fb60b411467ad501e1429a3487abca4664871d9ae0b46c8ba32", size = 16899477, upload-time = "2026-01-31T23:10:37.075Z" }, + { url = "https://files.pythonhosted.org/packages/09/a1/2a424e162b1a14a5bd860a464ab4e07513916a64ab1683fae262f735ccd2/numpy-2.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2653de5c24910e49c2b106499803124dde62a5a1fe0eedeaecf4309a5f639390", size = 17323429, upload-time = "2026-01-31T23:10:39.704Z" }, + { url = "https://files.pythonhosted.org/packages/ce/a2/73014149ff250628df72c58204822ac01d768697913881aacf839ff78680/numpy-2.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1ae241bbfc6ae276f94a170b14785e561cb5e7f626b6688cf076af4110887413", size = 18635109, upload-time = "2026-01-31T23:10:41.924Z" }, + { url = "https://files.pythonhosted.org/packages/6c/0c/73e8be2f1accd56df74abc1c5e18527822067dced5ec0861b5bb882c2ce0/numpy-2.4.2-cp311-cp311-win32.whl", hash = "sha256:df1b10187212b198dd45fa943d8985a3c8cf854aed4923796e0e019e113a1bda", size = 6237915, upload-time = "2026-01-31T23:10:45.26Z" }, + { url = "https://files.pythonhosted.org/packages/76/ae/e0265e0163cf127c24c3969d29f1c4c64551a1e375d95a13d32eab25d364/numpy-2.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:b9c618d56a29c9cb1c4da979e9899be7578d2e0b3c24d52079c166324c9e8695", size = 12607972, upload-time = "2026-01-31T23:10:47.021Z" }, + { url = "https://files.pythonhosted.org/packages/29/a5/c43029af9b8014d6ea157f192652c50042e8911f4300f8f6ed3336bf437f/numpy-2.4.2-cp311-cp311-win_arm64.whl", hash = "sha256:47c5a6ed21d9452b10227e5e8a0e1c22979811cad7dcc19d8e3e2fb8fa03f1a3", size = 10485763, upload-time = "2026-01-31T23:10:50.087Z" }, + { url = "https://files.pythonhosted.org/packages/51/6e/6f394c9c77668153e14d4da83bcc247beb5952f6ead7699a1a2992613bea/numpy-2.4.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:21982668592194c609de53ba4933a7471880ccbaadcc52352694a59ecc860b3a", size = 16667963, upload-time = "2026-01-31T23:10:52.147Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f8/55483431f2b2fd015ae6ed4fe62288823ce908437ed49db5a03d15151678/numpy-2.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40397bda92382fcec844066efb11f13e1c9a3e2a8e8f318fb72ed8b6db9f60f1", size = 14693571, upload-time = "2026-01-31T23:10:54.789Z" }, + { url = "https://files.pythonhosted.org/packages/2f/20/18026832b1845cdc82248208dd929ca14c9d8f2bac391f67440707fff27c/numpy-2.4.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:b3a24467af63c67829bfaa61eecf18d5432d4f11992688537be59ecd6ad32f5e", size = 5203469, upload-time = "2026-01-31T23:10:57.343Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/2eb97c8a77daaba34eaa3fa7241a14ac5f51c46a6bd5911361b644c4a1e2/numpy-2.4.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:805cc8de9fd6e7a22da5aed858e0ab16be5a4db6c873dde1d7451c541553aa27", size = 6550820, upload-time = "2026-01-31T23:10:59.429Z" }, + { url = "https://files.pythonhosted.org/packages/b1/91/b97fdfd12dc75b02c44e26c6638241cc004d4079a0321a69c62f51470c4c/numpy-2.4.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d82351358ffbcdcd7b686b90742a9b86632d6c1c051016484fa0b326a0a1548", size = 15663067, upload-time = "2026-01-31T23:11:01.291Z" }, + { url = "https://files.pythonhosted.org/packages/f5/c6/a18e59f3f0b8071cc85cbc8d80cd02d68aa9710170b2553a117203d46936/numpy-2.4.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e35d3e0144137d9fdae62912e869136164534d64a169f86438bc9561b6ad49f", size = 16619782, upload-time = "2026-01-31T23:11:03.669Z" }, + { url = "https://files.pythonhosted.org/packages/b7/83/9751502164601a79e18847309f5ceec0b1446d7b6aa12305759b72cf98b2/numpy-2.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adb6ed2ad29b9e15321d167d152ee909ec73395901b70936f029c3bc6d7f4460", size = 17013128, upload-time = "2026-01-31T23:11:05.913Z" }, + { url = "https://files.pythonhosted.org/packages/61/c4/c4066322256ec740acc1c8923a10047818691d2f8aec254798f3dd90f5f2/numpy-2.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8906e71fd8afcb76580404e2a950caef2685df3d2a57fe82a86ac8d33cc007ba", size = 18345324, upload-time = "2026-01-31T23:11:08.248Z" }, + { url = "https://files.pythonhosted.org/packages/ab/af/6157aa6da728fa4525a755bfad486ae7e3f76d4c1864138003eb84328497/numpy-2.4.2-cp312-cp312-win32.whl", hash = "sha256:ec055f6dae239a6299cace477b479cca2fc125c5675482daf1dd886933a1076f", size = 5960282, upload-time = "2026-01-31T23:11:10.497Z" }, + { url = "https://files.pythonhosted.org/packages/92/0f/7ceaaeaacb40567071e94dbf2c9480c0ae453d5bb4f52bea3892c39dc83c/numpy-2.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:209fae046e62d0ce6435fcfe3b1a10537e858249b3d9b05829e2a05218296a85", size = 12314210, upload-time = "2026-01-31T23:11:12.176Z" }, + { url = "https://files.pythonhosted.org/packages/2f/a3/56c5c604fae6dd40fa2ed3040d005fca97e91bd320d232ac9931d77ba13c/numpy-2.4.2-cp312-cp312-win_arm64.whl", hash = "sha256:fbde1b0c6e81d56f5dccd95dd4a711d9b95df1ae4009a60887e56b27e8d903fa", size = 10220171, upload-time = "2026-01-31T23:11:14.684Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f8/50e14d36d915ef64d8f8bc4a087fc8264d82c785eda6711f80ab7e620335/numpy-2.4.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:89f7268c009bc492f506abd6f5265defa7cb3f7487dc21d357c3d290add45082", size = 16833179, upload-time = "2026-01-31T23:12:53.5Z" }, + { url = "https://files.pythonhosted.org/packages/17/17/809b5cad63812058a8189e91a1e2d55a5a18fd04611dbad244e8aeae465c/numpy-2.4.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6dee3bb76aa4009d5a912180bf5b2de012532998d094acee25d9cb8dee3e44a", size = 14889755, upload-time = "2026-01-31T23:12:55.933Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ea/181b9bcf7627fc8371720316c24db888dcb9829b1c0270abf3d288b2e29b/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:cd2bd2bbed13e213d6b55dc1d035a4f91748a7d3edc9480c13898b0353708920", size = 5399500, upload-time = "2026-01-31T23:12:58.671Z" }, + { url = "https://files.pythonhosted.org/packages/33/9f/413adf3fc955541ff5536b78fcf0754680b3c6d95103230252a2c9408d23/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:cf28c0c1d4c4bf00f509fa7eb02c58d7caf221b50b467bcb0d9bbf1584d5c821", size = 6714252, upload-time = "2026-01-31T23:13:00.518Z" }, + { url = "https://files.pythonhosted.org/packages/91/da/643aad274e29ccbdf42ecd94dafe524b81c87bcb56b83872d54827f10543/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e04ae107ac591763a47398bb45b568fc38f02dbc4aa44c063f67a131f99346cb", size = 15797142, upload-time = "2026-01-31T23:13:02.219Z" }, + { url = "https://files.pythonhosted.org/packages/66/27/965b8525e9cb5dc16481b30a1b3c21e50c7ebf6e9dbd48d0c4d0d5089c7e/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:602f65afdef699cda27ec0b9224ae5dc43e328f4c24c689deaf77133dbee74d0", size = 16727979, upload-time = "2026-01-31T23:13:04.62Z" }, + { url = "https://files.pythonhosted.org/packages/de/e5/b7d20451657664b07986c2f6e3be564433f5dcaf3482d68eaecd79afaf03/numpy-2.4.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be71bf1edb48ebbbf7f6337b5bfd2f895d1902f6335a5830b20141fc126ffba0", size = 12502577, upload-time = "2026-01-31T23:13:07.08Z" }, +] + [[package]] name = "oauthlib" version = "3.3.1" @@ -1442,6 +1543,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, ] +[[package]] +name = "pycryptodome" +version = "3.23.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/a6/8452177684d5e906854776276ddd34eca30d1b1e15aa1ee9cefc289a33f5/pycryptodome-3.23.0.tar.gz", hash = "sha256:447700a657182d60338bab09fdb27518f8856aecd80ae4c6bdddb67ff5da44ef", size = 4921276, upload-time = "2025-05-17T17:21:45.242Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/6c/a1f71542c969912bb0e106f64f60a56cc1f0fabecf9396f45accbe63fa68/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:187058ab80b3281b1de11c2e6842a357a1f71b42cb1e15bce373f3d238135c27", size = 2495627, upload-time = "2025-05-17T17:20:47.139Z" }, + { url = "https://files.pythonhosted.org/packages/6e/4e/a066527e079fc5002390c8acdd3aca431e6ea0a50ffd7201551175b47323/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:cfb5cd445280c5b0a4e6187a7ce8de5a07b5f3f897f235caa11f1f435f182843", size = 1640362, upload-time = "2025-05-17T17:20:50.392Z" }, + { url = "https://files.pythonhosted.org/packages/50/52/adaf4c8c100a8c49d2bd058e5b551f73dfd8cb89eb4911e25a0c469b6b4e/pycryptodome-3.23.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67bd81fcbe34f43ad9422ee8fd4843c8e7198dd88dd3d40e6de42ee65fbe1490", size = 2182625, upload-time = "2025-05-17T17:20:52.866Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e9/a09476d436d0ff1402ac3867d933c61805ec2326c6ea557aeeac3825604e/pycryptodome-3.23.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8987bd3307a39bc03df5c8e0e3d8be0c4c3518b7f044b0f4c15d1aa78f52575", size = 2268954, upload-time = "2025-05-17T17:20:55.027Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c5/ffe6474e0c551d54cab931918127c46d70cab8f114e0c2b5a3c071c2f484/pycryptodome-3.23.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa0698f65e5b570426fc31b8162ed4603b0c2841cbb9088e2b01641e3065915b", size = 2308534, upload-time = "2025-05-17T17:20:57.279Z" }, + { url = "https://files.pythonhosted.org/packages/18/28/e199677fc15ecf43010f2463fde4c1a53015d1fe95fb03bca2890836603a/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:53ecbafc2b55353edcebd64bf5da94a2a2cdf5090a6915bcca6eca6cc452585a", size = 2181853, upload-time = "2025-05-17T17:20:59.322Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ea/4fdb09f2165ce1365c9eaefef36625583371ee514db58dc9b65d3a255c4c/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:156df9667ad9f2ad26255926524e1c136d6664b741547deb0a86a9acf5ea631f", size = 2342465, upload-time = "2025-05-17T17:21:03.83Z" }, + { url = "https://files.pythonhosted.org/packages/22/82/6edc3fc42fe9284aead511394bac167693fb2b0e0395b28b8bedaa07ef04/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:dea827b4d55ee390dc89b2afe5927d4308a8b538ae91d9c6f7a5090f397af1aa", size = 2267414, upload-time = "2025-05-17T17:21:06.72Z" }, + { url = "https://files.pythonhosted.org/packages/59/fe/aae679b64363eb78326c7fdc9d06ec3de18bac68be4b612fc1fe8902693c/pycryptodome-3.23.0-cp37-abi3-win32.whl", hash = "sha256:507dbead45474b62b2bbe318eb1c4c8ee641077532067fec9c1aa82c31f84886", size = 1768484, upload-time = "2025-05-17T17:21:08.535Z" }, + { url = "https://files.pythonhosted.org/packages/54/2f/e97a1b8294db0daaa87012c24a7bb714147c7ade7656973fd6c736b484ff/pycryptodome-3.23.0-cp37-abi3-win_amd64.whl", hash = "sha256:c75b52aacc6c0c260f204cbdd834f76edc9fb0d8e0da9fbf8352ef58202564e2", size = 1799636, upload-time = "2025-05-17T17:21:10.393Z" }, + { url = "https://files.pythonhosted.org/packages/18/3d/f9441a0d798bf2b1e645adc3265e55706aead1255ccdad3856dbdcffec14/pycryptodome-3.23.0-cp37-abi3-win_arm64.whl", hash = "sha256:11eeeb6917903876f134b56ba11abe95c0b0fd5e3330def218083c7d98bbcb3c", size = 1703675, upload-time = "2025-05-17T17:21:13.146Z" }, + { url = "https://files.pythonhosted.org/packages/d9/12/e33935a0709c07de084d7d58d330ec3f4daf7910a18e77937affdb728452/pycryptodome-3.23.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ddb95b49df036ddd264a0ad246d1be5b672000f12d6961ea2c267083a5e19379", size = 1623886, upload-time = "2025-05-17T17:21:20.614Z" }, + { url = "https://files.pythonhosted.org/packages/22/0b/aa8f9419f25870889bebf0b26b223c6986652bdf071f000623df11212c90/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e95564beb8782abfd9e431c974e14563a794a4944c29d6d3b7b5ea042110b4", size = 1672151, upload-time = "2025-05-17T17:21:22.666Z" }, + { url = "https://files.pythonhosted.org/packages/d4/5e/63f5cbde2342b7f70a39e591dbe75d9809d6338ce0b07c10406f1a140cdc/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14e15c081e912c4b0d75632acd8382dfce45b258667aa3c67caf7a4d4c13f630", size = 1664461, upload-time = "2025-05-17T17:21:25.225Z" }, + { url = "https://files.pythonhosted.org/packages/d6/92/608fbdad566ebe499297a86aae5f2a5263818ceeecd16733006f1600403c/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7fc76bf273353dc7e5207d172b83f569540fc9a28d63171061c42e361d22353", size = 1702440, upload-time = "2025-05-17T17:21:27.991Z" }, + { url = "https://files.pythonhosted.org/packages/d1/92/2eadd1341abd2989cce2e2740b4423608ee2014acb8110438244ee97d7ff/pycryptodome-3.23.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:45c69ad715ca1a94f778215a11e66b7ff989d792a4d63b68dc586a1da1392ff5", size = 1803005, upload-time = "2025-05-17T17:21:31.37Z" }, +] + [[package]] name = "pycryptodomex" version = "3.23.0" @@ -1781,10 +1906,19 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/9b/41/bb668a6e4192303542d2d90c3b38d564af3c17c61bd7d4039af4f29405fe/secp256k1-0.14.0.tar.gz", hash = "sha256:82c06712d69ef945220c8b53c1a0d424c2ff6a1f64aee609030df79ad8383397", size = 2420607, upload-time = "2021-11-06T01:36:10.707Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/68/6f/be058f4c36f488c3528e5800559a4857e64b1b6e852612533dec4bac63cf/secp256k1-0.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2cf51c4f6892000a781d09cecd80466f4b9bea74b31b0470704ebcf26ae003ce", size = 1298106, upload-time = "2026-01-29T16:26:23.572Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c0/edfd6d53e2a7b19aace28dccd6b3359c52ddd1d905d5a060b7961a1bda3e/secp256k1-0.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f54320f5dac8b740765e1ff5e47fd3cd2604ec334104c8f9113d29666b8ce6", size = 1498901, upload-time = "2026-01-29T16:26:25.89Z" }, { url = "https://files.pythonhosted.org/packages/09/46/5d3ca364058d39160e3623f0babafe78c2236d359e86924aa07524377c98/secp256k1-0.14.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f666c67dcf1dc69e1448b2ede5e12aaf382b600204a61dbc65e4f82cea444405", size = 1376587, upload-time = "2022-01-24T12:36:39.127Z" }, + { url = "https://files.pythonhosted.org/packages/a6/c6/25b43bd42e24c8ac5babe262b40af0d6cf76ab035ad5e6b894eb9038ab4c/secp256k1-0.14.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53c779fd35328598522eb2b6cdb6d104e80440cb301ccc312b52bf62e5ea78ee", size = 1494595, upload-time = "2026-01-29T16:26:27.391Z" }, { url = "https://files.pythonhosted.org/packages/ce/e2/5b1616593ed1fa0e07e87b9f5118dc098bd1ddb2a6a7698d82b0ff85ad3f/secp256k1-0.14.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fcabb3c3497a902fb61eec72d1b69bf72747d7bcc2a732d56d9319a1e8322262", size = 1362187, upload-time = "2022-01-24T12:36:41.677Z" }, { url = "https://files.pythonhosted.org/packages/c9/9c/8148f74dd1fc65d0b97c8cbb101b468e27a2e93a3f291807d0d8ebe4bbf3/secp256k1-0.14.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7a27c479ab60571502516a1506a562d0a9df062de8ad645313fabfcc97252816", size = 1376363, upload-time = "2022-01-24T12:36:44.314Z" }, { url = "https://files.pythonhosted.org/packages/64/11/ff6d18314bc05a8f66619959a61be2fb6f37793d73e1dd106954b0978d92/secp256k1-0.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f4b9306bff6dde020444dfee9ca9b9f5b20ca53a2c0b04898361a3f43d5daf2e", size = 1369109, upload-time = "2022-01-24T12:36:46.782Z" }, + { url = "https://files.pythonhosted.org/packages/77/12/4c9815a819816587df70aa38fe7d09b54724a0b1b9b8e8ea2af1c205f2a5/secp256k1-0.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:539d1d9750299ec4e8df6211978ba78779f5095c7ef19985313f03d1d1b816bd", size = 1298105, upload-time = "2026-01-29T16:26:28.697Z" }, + { url = "https://files.pythonhosted.org/packages/b1/86/f01ee0f4c44e12933c460f2b868a3888b93a7c7f4e9fc9be173401b55e8d/secp256k1-0.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85d597a59e3918b0e41181a1c872851ac2e6137882de7f0487b8c42b25333ada", size = 1498906, upload-time = "2026-01-29T16:26:30.138Z" }, + { url = "https://files.pythonhosted.org/packages/05/c8/79f2990b72556c3f416ecfde2116a08afb41e324f51b8bf61268d7b72715/secp256k1-0.14.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:393d189b4ada9ab3de0b053f484a3b7e86024f4b8cd36616c05f07dbae3ca180", size = 1494612, upload-time = "2026-01-29T16:26:32.252Z" }, + { url = "https://files.pythonhosted.org/packages/a4/e8/8dd140270b4e12a7f5876f1641f996854d700866352875f161f770b69ebb/secp256k1-0.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e4ec14534c1e8b8991376915ef059b7a3e62366aeda60df50b3932ad6529d26a", size = 1298100, upload-time = "2026-01-29T16:26:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/9c/6c/e63892de8d7582ab30602ccc1cf0ecd88a30b1a09424eb847c863fd46d9f/secp256k1-0.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1041694e429eb465123cb742911d2aad5cbd9e0cf2891aaaf794a887938647d1", size = 1499269, upload-time = "2026-01-29T16:26:35.717Z" }, + { url = "https://files.pythonhosted.org/packages/b8/5c/2faa8c523c0204af249890eb51b697e9a19d59d101625149d7b4f482e894/secp256k1-0.14.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf03e6d45892172046d4e085d5cc91d13a73a465c0f4c8b5633d823b0ca667e2", size = 1494878, upload-time = "2026-01-29T16:26:37.857Z" }, ] [[package]] @@ -1805,6 +1939,43 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c0/44/21d6bf170bf40b41396480d8d49ad640bca3f2b02139cd52aa1e272830a5/shortuuid-1.0.13-py3-none-any.whl", hash = "sha256:a482a497300b49b4953e15108a7913244e1bb0d41f9d332f5e9925dba33a3c5a", size = 10529, upload-time = "2024-03-11T20:11:04.807Z" }, ] +[[package]] +name = "silnt" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "bitcoinlib" }, + { name = "embit" }, + { name = "lnbits" }, +] + +[package.dev-dependencies] +dev = [ + { name = "black" }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [ + { name = "bitcoinlib", specifier = ">=0.6.12.1" }, + { name = "embit", specifier = ">=0.8.0" }, + { name = "lnbits", specifier = ">1" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "black" }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "ruff" }, +] + [[package]] name = "six" version = "1.17.0" diff --git a/views.py b/views.py index 8a2844f..5f8703b 100644 --- a/views.py +++ b/views.py @@ -4,16 +4,15 @@ from lnbits.decorators import check_user_exists from lnbits.helpers import template_renderer -example_ext_generic = APIRouter(tags=["example"]) +silnt_generic_router = APIRouter() -@example_ext_generic.get( - "/", description="Example generic endpoint", response_class=HTMLResponse -) -async def index( - request: Request, - user: User = Depends(check_user_exists), -): - return template_renderer(["example/templates"]).TemplateResponse( - request, "example/index.html", {"user": user.json()} - ) +def silnt_renderer(): + return template_renderer(["silnt/templates"]) + + +@silnt_generic_router.get("/", response_class=HTMLResponse) +async def index(request: Request, user: User = Depends(check_user_exists)): + return silnt_renderer().TemplateResponse( + "silnt/index.html", {"request": request, "user": user.json()} + ) \ No newline at end of file diff --git a/views_api.py b/views_api.py index 021227c..95ce37d 100644 --- a/views_api.py +++ b/views_api.py @@ -1,35 +1,401 @@ +import json from http import HTTPStatus import httpx -from fastapi import APIRouter, Depends, HTTPException -from lnbits.decorators import require_invoice_key +from embit import finalizer, script +from embit.ec import PublicKey +from embit.networks import NETWORKS +from .helpers.wallet import generate_silent_wallet_address, decrypt_mnemonic +# from embit.psbt import PSBT, DerivationPath +# from embit.transaction import Transaction, TransactionInput, TransactionOutput +from fastapi import APIRouter, Depends, HTTPException, Query, Request +from lnbits.core.models import WalletTypeInfo +from lnbits.decorators import require_admin_key, require_invoice_key +from lnbits.helpers import urlsafe_short_hash, decrypt_internal_message +from loguru import logger -from .models import Example +from .crud import ( + get_silnt_wallets, + create_silnt_wallet, + delete_silnt_wallet, + delete_utxos_for_wallet, + get_sp_address, + get_hr_address, + update_hr_address, + update_last_height, + get_silnt_wallet +) + +from .models import ( + # Address, + Config, + CreateWallet, + # ExtractPsbt, + # ExtractTx, + # SerializedTransaction, + # SignedTransaction, + WalletAccount, +) + +silnt_api_router = APIRouter() -example_ext_api = APIRouter() -# views_api.py is for you API endpoints that could be hit by another service +@silnt_api_router.get("/api/v1/wallet", status_code=HTTPStatus.OK) +async def api_wallets_retrieve( + network: str = Query("Mainnet"), + key_info: WalletTypeInfo = Depends(require_invoice_key), +) -> list[WalletAccount]: + return await get_silnt_wallets(key_info.wallet.user, network) -@example_ext_api.get("/api/v1/test/{example_data}", description="Example API endpoint") -async def api_example(example_data: str) -> Example: - if example_data != "00000000": +@silnt_api_router.get( + "/api/v1/wallet/{wallet_id}", dependencies=[Depends(require_invoice_key)] +) +async def api_wallet_retrieve(wallet_id: str) -> WalletAccount: + silnt_wallet = await get_silnt_wallet(wallet_id) + + if not silnt_wallet: raise HTTPException( - status_code=HTTPStatus.BAD_REQUEST, - detail="Invalid example data", + status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." + ) + + return silnt_wallet + + +@silnt_api_router.post("/api/v1/wallet", status_code=HTTPStatus.OK) +async def api_wallet_create( + data: CreateWallet, key_info: WalletTypeInfo = Depends(require_admin_key) +) -> str: + try: + new_wallet = WalletAccount( + id=urlsafe_short_hash(), + user=key_info.wallet.user, + title=data.title, + balance=0, + hr_address=data.hr_address, + network=data.network, + last_height=int(data.last_height), + sp_address='', + spend_key='', + scan_secret='' + ) + (sp_address, scan_secret, spend_key) = generate_silent_wallet_address(data.mnemonic) + if not all([sp_address,scan_secret,spend_key]): + raise ValueError( + f"Wallet '{data.title}' cannot be created with given mnemonic!" + ) + wallets = await get_silnt_wallets(key_info.wallet.user, data.network) + existing_wallet = next( + ( + ew + for ew in wallets + if ew.sp_address == sp_address + and ew.network == new_wallet.network + ), + None, ) - # Do some python things and return the data - return Example(id="2", wallet=example_data) + logger.info(existing_wallet) + if existing_wallet: + if data.hr_address and data.hr_address != existing_wallet.hr_address: + await update_hr_address(existing_wallet.id, data.hr_address) + if data.last_height and data.last_height != existing_wallet.last_height: + await update_last_height(existing_wallet.id, data.last_height) + else: + raise ValueError( + f"Wallet '{data.title}' already exists!" + ) + return '' + new_wallet.scan_secret = scan_secret + new_wallet.spend_key = spend_key + new_wallet.sp_address = sp_address + # logger.info(new_wallet) + wallet = await create_silnt_wallet(new_wallet) + except Exception as exc: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, detail=str(exc) + ) from exc + return '' + +@silnt_api_router.post("/api/v1/wallet{wallet_id}", status_code=HTTPStatus.OK) +async def api_wallet_update( + wallet_id: str, data: CreateWallet, key_info: WalletTypeInfo = Depends(require_admin_key) +) -> str: + try: + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." + ) + if data.hr_address and data.hr_address != wallet.hr_address: + await update_hr_address(wallet.id, data.hr_address) + if data.last_height and int(data.last_height) != wallet.last_height: + await update_last_height(wallet.id, int(data.last_height)) + except Exception as exc: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, detail=str(exc) + ) from exc + return '' -@example_ext_api.get( - "/api/v1/vetted", - description="Get the vetted extension readme", - dependencies=[Depends(require_invoice_key)], +@silnt_api_router.delete( + "/api/v1/wallet/{wallet_id}", dependencies=[Depends(require_admin_key)] ) -async def api_get_vetted(): - async with httpx.AsyncClient() as client: - resp = await client.get( - "https://raw.githubusercontent.com/lnbits/lnbits-extensions/main/README.md" +async def api_wallet_delete(wallet_id: str): + wallet = await get_silnt_wallet(wallet_id) + + if not wallet: + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." + ) + + await delete_silnt_wallet(wallet_id) + await delete_utxos_for_wallet(wallet_id) + + return "", HTTPStatus.NO_CONTENT + + +#############################ADDRESSES########################## + + +# @silnt_api_router.get( +# "/api/v1/address/{wallet_id}", dependencies=[Depends(require_invoice_key)] +# ) +# async def api_fresh_address(wallet_id: str) -> Address: +# address = await get_fresh_address(wallet_id) +# assert address +# return address + + +# @silnt_api_router.put( +# "/api/v1/address/{address_id}", dependencies=[Depends(require_admin_key)] +# ) +# async def api_update_address(address_id: str, req: Request): +# address = await get_address_by_id(address_id) +# if not address: +# raise HTTPException( +# status_code=HTTPStatus.NOT_FOUND, detail="Address does not exist." +# ) + +# body = await req.json() +# # amount is only updated if the address has history +# if "amount" in body: +# address.amount = int(body["amount"]) +# address.has_activity = True + +# if "note" in body: +# address.note = body["note"] + +# address = await update_address(address) + +# wallet = ( +# await get_watch_wallet(address.wallet) +# if address.branch_index == 0 and address.amount != 0 +# else None +# ) + +# if wallet and wallet.address_no < address.address_index: +# wallet.address_no = address.address_index +# await update_watch_wallet(wallet) +# return address + + +@silnt_api_router.get("/api/v1/address/{wallet_id}") +async def api_get_address( + wallet_id, key_info: WalletTypeInfo = Depends(require_invoice_key) +) -> str: + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." ) - return resp.text + sp_address = await get_sp_address(wallet_id) + assert sp_address, f"Silent Payment address doesn't exist for wallet: {wallet_id}" + hr_address = await get_hr_address(wallet_id) + return sp_address,hr_address + + + + +# @silnt_api_router.post("/api/v1/psbt", dependencies=[Depends(require_admin_key)]) +# async def api_psbt_create(data: CreatePsbt): +# try: +# vin = [ +# TransactionInput(bytes.fromhex(inp.tx_id), inp.vout) for inp in data.inputs +# ] +# vout = [ +# TransactionOutput(out.amount, script.address_to_scriptpubkey(out.address)) +# for out in data.outputs +# ] + +# descriptors = {} +# for _, masterpub in enumerate(data.masterpubs): +# descriptors[masterpub.id] = parse_key(masterpub.public_key) + +# inputs_extra: list[dict] = [] + +# for inp in data.inputs: +# bip32_derivations = {} +# descriptor = descriptors[inp.wallet][0] +# d = descriptor.derive(inp.address_index, inp.branch_index) +# for k in d.keys: +# bip32_derivations[PublicKey.parse(k.sec())] = DerivationPath( +# k.origin.fingerprint, k.origin.derivation +# ) +# inputs_extra.append( +# { +# "bip32_derivations": bip32_derivations, +# "non_witness_utxo": Transaction.from_string(inp.tx_hex), +# } +# ) + +# tx = Transaction(vin=vin, vout=vout) +# psbt = PSBT(tx) + +# for i, inp_extra in enumerate(inputs_extra): +# psbt.inputs[i].bip32_derivations = inp_extra["bip32_derivations"] +# psbt.inputs[i].non_witness_utxo = inp_extra.get("non_witness_utxo", None) + +# outputs_extra = [] +# bip32_derivations = {} +# for out in data.outputs: +# if out.branch_index == 1: +# assert out.wallet +# descriptor = descriptors[out.wallet][0] +# d = descriptor.derive(out.address_index, out.branch_index) +# for k in d.keys: +# bip32_derivations[PublicKey.parse(k.sec())] = DerivationPath( +# k.origin.fingerprint, k.origin.derivation +# ) +# outputs_extra.append({"bip32_derivations": bip32_derivations}) + +# for i, out_extra in enumerate(outputs_extra): +# psbt.outputs[i].bip32_derivations = out_extra["bip32_derivations"] + +# return psbt.to_string() + +# except Exception as exc: +# raise HTTPException( +# status_code=HTTPStatus.BAD_REQUEST, detail=str(exc) +# ) from exc + + +# @silnt_api_router.put( +# "/api/v1/psbt/utxos", dependencies=[Depends(require_admin_key)] +# ) +# async def api_psbt_utxos_tx(req: Request): +# """Extract previous unspent transaction outputs (tx_id, vout) from PSBT""" + +# body = await req.json() +# try: +# psbt = PSBT.from_base64(body["psbtBase64"]) +# res = [] +# for _, inp in enumerate(psbt.inputs): +# res.append({"tx_id": inp.txid.hex(), "vout": inp.vout}) + +# return res +# except Exception as exc: +# raise HTTPException( +# status_code=HTTPStatus.BAD_REQUEST, detail=str(exc) +# ) from exc + + +# @silnt_api_router.put( +# "/api/v1/psbt/extract", dependencies=[Depends(require_admin_key)] +# ) +# async def api_psbt_extract_tx(data: ExtractPsbt) -> SignedTransaction: +# network = NETWORKS["main"] if data.network == "Mainnet" else NETWORKS["test"] +# try: +# psbt = PSBT.from_base64(data.psbt_base64) +# for i, inp in enumerate(data.inputs): +# psbt.inputs[i].non_witness_utxo = Transaction.from_string(inp.tx_hex) + +# final_psbt = finalizer.finalize_psbt(psbt) +# if not final_psbt: +# raise ValueError("PSBT cannot be finalized!") + +# tx_hex = final_psbt.to_string() +# transaction = Transaction.from_string(tx_hex) +# tx = { +# "locktime": transaction.locktime, +# "version": transaction.version, +# "outputs": [], +# "fee": psbt.fee(), +# } + +# for out in transaction.vout: +# tx["outputs"].append( +# {"amount": out.value, "address": out.script_pubkey.address(network)} +# ) +# signed_tx = SignedTransaction(tx_hex=tx_hex, tx_json=json.dumps(tx)) +# return signed_tx +# except Exception as exc: +# raise HTTPException( +# status_code=HTTPStatus.BAD_REQUEST, detail=str(exc) +# ) from exc + + +# @silnt_api_router.put( +# "/api/v1/tx/extract", dependencies=[Depends(require_admin_key)] +# ) +# async def api_extract_tx(data: ExtractTx): +# network = NETWORKS["main"] if data.network == "mainnet" else NETWORKS["test"] +# try: +# transaction = Transaction.from_string(data.tx_hex) +# tx = { +# "locktime": transaction.locktime, +# "version": transaction.version, +# "outputs": [], +# } + +# for out in transaction.vout: +# tx["outputs"].append( +# {"amount": out.value, "address": out.script_pubkey.address(network)} +# ) +# return {"tx_json": tx} +# except Exception as exc: +# raise HTTPException( +# status_code=HTTPStatus.BAD_REQUEST, detail=str(exc) +# ) from exc + + +# @silnt_api_router.post("/api/v1/tx") +# async def api_tx_broadcast( +# data: SerializedTransaction, key_info: WalletTypeInfo = Depends(require_admin_key) +# ): +# try: +# config = await get_config(key_info.wallet.user) +# if not config: +# raise ValueError( +# "Cannot broadcast transaction. Mempool endpoint not defined!" +# ) + +# endpoint = ( +# config.mempool_endpoint +# if config.network == "mainnet" +# else config.mempool_endpoint + "/testnet" +# ) +# async with httpx.AsyncClient() as client: +# r = await client.post(endpoint + "/api/tx", content=data.tx_hex) +# r.raise_for_status() +# tx_id = r.text +# return tx_id +# except Exception as exc: +# raise HTTPException( +# status_code=HTTPStatus.BAD_REQUEST, detail=str(exc) +# ) from exc + + +# @silnt_api_router.put("/api/v1/config") +# async def api_update_config( +# data: Config, key_info: WalletTypeInfo = Depends(require_admin_key) +# ) -> Config: +# config = await update_config(data, user=key_info.wallet.user) +# return config + + +# @silnt_api_router.get("/api/v1/config") +# async def api_get_config( +# key_info: WalletTypeInfo = Depends(require_invoice_key), +# ) -> Config: +# config = await get_config(key_info.wallet.user) +# return config From aee231e828706f73779d03fbe2f0ee570cfcc408 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Sat, 21 Mar 2026 23:30:00 +0000 Subject: [PATCH 03/83] utxo redesign --- helpers/wallet.py | 2 +- models.py | 5 + static/components/utxo-list.js | 33 +- static/components/wallet-config.js | 14 +- static/js/index.js | 295 ++++-------------- templates/silnt/components/utxo-list.html | 146 +++++---- templates/silnt/components/wallet-config.html | 43 ++- templates/silnt/index.html | 140 +++------ views_api.py | 50 ++- 9 files changed, 277 insertions(+), 451 deletions(-) diff --git a/helpers/wallet.py b/helpers/wallet.py index 313b3d8..2602125 100644 --- a/helpers/wallet.py +++ b/helpers/wallet.py @@ -38,7 +38,7 @@ def encode_silent_payment_address(B_scan: Point, B_m: Point, hrp: str = 'tsp', v raise ValueError('ERROR: Invalid data.') return ret -def generate_silent_wallet_address(mnemonic) -> tuple: +def generate_silent_wallet_address(mnemonic) -> tuple: seed = get_seed(mnemonic) key_material = generate_hardened_keys(seed) # Receiver's scan and spend public key diff --git a/models.py b/models.py index 4f1853b..d9fb28e 100644 --- a/models.py +++ b/models.py @@ -4,6 +4,11 @@ from pydantic import BaseModel +class ScanConfig(BaseModel): + blindbit_url: str + auth_user: str = "" + auth_pass: str = "" + class CreateWallet(BaseModel): mnemonic: str = Query("") title: str = Query("") diff --git a/static/components/utxo-list.js b/static/components/utxo-list.js index 545fdee..d4e67aa 100644 --- a/static/components/utxo-list.js +++ b/static/components/utxo-list.js @@ -32,13 +32,7 @@ window.app.component('utxo-list', { name: 'status', align: 'center', label: 'Status', - sortable: true - }, - { - name: 'address', - align: 'left', - label: 'Address', - field: 'address', + field: 'utxo_state', sortable: true }, { @@ -52,15 +46,9 @@ window.app.component('utxo-list', { name: 'date', align: 'left', label: 'Date', - field: 'date', - sortable: true - }, - { - name: 'wallet', - align: 'left', - label: 'Account', - field: 'wallet', - sortable: true + field: 'timestamp', + sortable: true, + sort: (a, b) => a - b } ], pagination: { @@ -84,6 +72,16 @@ window.app.component('utxo-list', { return this.utxosTable.columns.filter(c => c.selectable ? this.selectable : true ) + }, + unspentTotal: function () { + return (this.utxos || []) + .filter(u => u.utxo_state === 'unspent') + .reduce((t, u) => t + (u.amount || 0), 0) + }, + spentTotal: function () { + return (this.utxos || []) + .filter(u => u.utxo_state === 'spent') + .reduce((t, u) => t + (u.amount || 0), 0) } }, @@ -91,6 +89,7 @@ window.app.component('utxo-list', { satBtc(val, showUnit = true) { return satOrBtc(val, showUnit, this.satsDenominated) }, + // Kept for compatibility but not used for blindbit UTXOs (no wallet account) getWalletName: function (walletId) { const wallet = (this.accounts || []).find(wl => wl.id === walletId) return wallet ? wallet.title : 'unknown' @@ -143,4 +142,4 @@ window.app.component('utxo-list', { }, created: async function () {} -}) +}) \ No newline at end of file diff --git a/static/components/wallet-config.js b/static/components/wallet-config.js index ef653d0..094ca26 100644 --- a/static/components/wallet-config.js +++ b/static/components/wallet-config.js @@ -20,6 +20,9 @@ window.app.component('wallet-config', { }, set(value) { value.isLoaded = true + // Ensure blindbit auth fields are always present + value.blindbit_user = value.blindbit_user || '' + value.blindbit_pass = value.blindbit_pass || '' this.internalConfig = JSON.parse(JSON.stringify(value)) this.$emit( 'update:config-data', @@ -29,15 +32,12 @@ window.app.component('wallet-config', { } }, - methods: { - satBtc(val, showUnit = true) { - return satOrBtc(val, showUnit, this.config.sats_denominated) - }, + methods: { updateConfig: async function () { try { const {data} = await LNbits.api.request( 'PUT', - '/watchonly/api/v1/config', + '/silnt/api/v1/config', this.adminkey, this.config ) @@ -51,7 +51,7 @@ window.app.component('wallet-config', { try { const {data} = await LNbits.api.request( 'GET', - '/watchonly/api/v1/config', + '/silnt/api/v1/config', this.adminkey ) this.config = data @@ -63,4 +63,4 @@ window.app.component('wallet-config', { created: async function () { await this.getConfig() } -}) +}) \ No newline at end of file diff --git a/static/js/index.js b/static/js/index.js index c0abda7..ce99e1f 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -40,8 +40,7 @@ window.app = Vue.createApp({ network: null, showEnterSignedPsbt: false, - signedBase64Psbt: null, - + signedBase64Psbt: null, connectedDeviceType: null } }, @@ -53,101 +52,10 @@ window.app = Vue.createApp({ hostname += '/testnet' } return hostname - }, - signerDevice: function () { - if (this.connectedDeviceType === 'trezor-device') { - return this.$refs.trezorSigner - } - return this.$refs.serialSigner - } + } }, methods: { - updateAmountForAddress: async function (addressData, amount = 0) { - try { - const wallet = this.g.user.wallets[0] - addressData.amount = amount - if (!addressData.isChange) { - const addressWallet = this.walletAccounts.find( - w => w.id === addressData.wallet - ) - if ( - addressWallet && - addressWallet.address_no < addressData.addressIndex - ) { - addressWallet.address_no = addressData.addressIndex - } - } - - // todo: account deleted - await LNbits.api.request( - 'PUT', - `/watchonly/api/v1/address/${addressData.id}`, - wallet.adminkey, - {amount} - ) - } catch (err) { - addressData.error = 'Failed to refresh amount for address' - this.$q.notify({ - type: 'warning', - message: `Failed to refresh amount for address ${addressData.address}`, - timeout: 10000 - }) - LNbits.utils.notifyApiError(err) - } - }, - updateNoteForAddress: async function ({addressId, note}) { - try { - const wallet = this.g.user.wallets[0] - await LNbits.api.request( - 'PUT', - `/watchonly/api/v1/address/${addressId}`, - wallet.adminkey, - {note} - ) - const updatedAddress = - this.addresses.find(a => a.id === addressId) || {} - updatedAddress.note = note - } catch (err) { - LNbits.utils.notifyApiError(err) - } - }, - - //################### ADDRESS HISTORY ################### - addressHistoryFromTxs: function (addressData, txs) { - const addressHistory = [] - txs.forEach(tx => { - const sent = tx.vin - .filter( - vin => vin.prevout.scriptpubkey_address === addressData.address - ) - .map(vin => mapInputToSentHistory(tx, addressData, vin)) - - const received = tx.vout - .filter(vout => vout.scriptpubkey_address === addressData.address) - .map(vout => mapOutputToReceiveHistory(tx, addressData, vout)) - addressHistory.push(...sent, ...received) - }) - return addressHistory - }, - - markSameTxAddressHistory: function () { - this.history - .filter(s => s.sent) - .forEach((el, i, arr) => { - if (el.isSubItem) return - - const sameTxItems = arr.slice(i + 1).filter(e => e.txId === el.txId) - if (!sameTxItems.length) return - sameTxItems.forEach(e => { - e.isSubItem = true - }) - - el.totalAmount = - el.amount + sameTxItems.reduce((t, e) => (t += e.amount || 0), 0) - el.sameTxItems = sameTxItems - }) - }, //################### PAYMENT ################### @@ -181,71 +89,59 @@ window.app = Vue.createApp({ }, //################### UTXOs ################### - scanAllAddresses: async function () { - await this.refreshAddresses() - this.history = [] - let addresses = this.addresses - this.utxos.data = [] - this.utxos.total = 0 - // Loop while new funds are found on the gap adresses. - // Use 1000 limit as a safety check (scan 20 000 addresses max) - for (let i = 0; i < 1000 && addresses.length; i++) { - await this.updateUtxosForAddresses(addresses) - const oldAddresses = this.addresses.slice() - await this.refreshAddresses() - const newAddresses = this.addresses.slice() - // check if gap addresses have been extended - addresses = newAddresses.filter( - newAddr => !oldAddresses.find(oldAddr => oldAddr.id === newAddr.id) - ) - if (addresses.length) { - this.$q.notify({ - type: 'positive', - message: 'Funds found! Scanning for more...', - timeout: 10000 - }) - } + scanSilentPayAddress: async function () { + if (!this.config.blindbit_url) { + this.$q.notify({ + type: 'warning', + message: 'BlindBit Scan URL not configured. Open Settings to set it.', + timeout: 10000 + }) + return } - }, - scanAddressWithAmount: async function () { - this.utxos.data = [] - this.utxos.total = 0 - this.history = [] - const addresses = this.addresses.filter(a => a.hasActivity) - await this.updateUtxosForAddresses(addresses) - }, - scanAddress: async function (addressData) { - this.updateUtxosForAddresses([addressData]) - this.$q.notify({ - type: 'positive', - message: 'Address Rescanned', - timeout: 10000 - }) - }, - refreshAddresses: async function () { - if (!this.walletAccounts) return - this.addresses = [] - for (const {id, type} of this.walletAccounts) { - const newAddresses = await this.getAddressesForWallet(id) - const uniqueAddresses = newAddresses.filter( - newAddr => !this.addresses.find(a => a.address === newAddr.address) + try { + const {data} = await LNbits.api.request( + 'POST', + '/silnt/api/v1/scan', + this.g.user.wallets[0].inkey, + { + blindbit_url: this.blindbit_url, + auth_user: this.blindbit.user, + auth_pass: this.blindbit.pass + } ) - const lastActiveAddress = - uniqueAddresses.filter(a => !a.isChange && a.hasActivity).pop() || {} + // Map blindbit UTXOs into the utxos list + this.utxos.data = (data.utxos || []).map(u => ({ + txid: u.txid, + amount: u.amount, + utxo_state: u.utxo_state, + label: u.label, + timestamp: u.timestamp + })) + this.utxos.total = this.utxos.data.reduce( + (total, u) => total + (u.amount || 0), 0 + ) - uniqueAddresses.forEach(a => { - a.expanded = false - a.accountType = type - a.gapLimitExceeded = - !a.isChange && - a.addressIndex > - lastActiveAddress.addressIndex + DEFAULT_RECEIVE_GAP_LIMIT + const height = data.height?.height + this.$q.notify({ + type: 'positive', + message: `Scan complete. ${this.utxos.data.length} UTXO(s) found.` + + (height ? ` Scanned to block ${height}.` : ''), + timeout: 10000 + }) + this.tab = 'utxos' + } catch (err) { + this.$q.notify({ + type: 'warning', + message: 'Failed to connect to blindbit-scan', + timeout: 10000 }) - this.addresses.push(...uniqueAddresses) + LNbits.utils.notifyApiError(err) + } finally { + this.scan.scanning = false + this.scan.scanIndex = 1 } - this.$emit('update:addresses', this.addresses) - }, + }, getAddressesForWallet: async function (walletId) { try { const {data} = await LNbits.api.request( @@ -264,67 +160,6 @@ window.app = Vue.createApp({ } return [] }, - updateUtxosForAddresses: async function (addresses = []) { - this.scan = {scanning: true, scanCount: addresses.length, scanIndex: 0} - - try { - for (addrData of addresses) { - const addressHistory = await this.getAddressTxsDelayed(addrData) - // remove old entries - this.history = this.history.filter( - h => h.address !== addrData.address - ) - - // add new entries - this.history.push(...addressHistory) - this.history.sort((a, b) => (!a.height ? -1 : b.height - a.height)) - this.markSameTxAddressHistory() - - if (addressHistory.length) { - // search only if it ever had any activity - const utxos = await this.getAddressTxsUtxoDelayed(addrData.address) - this.updateUtxosForAddress(addrData, utxos) - } - - this.scan.scanIndex++ - } - } catch (error) { - console.error(error) - this.$q.notify({ - type: 'warning', - message: 'Failed to scan addresses', - timeout: 10000 - }) - } finally { - this.scan.scanning = false - } - }, - updateUtxosForAddress: function (addressData, utxos = []) { - const wallet = - this.walletAccounts.find(w => w.id === addressData.wallet) || {} - - const newUtxos = utxos.map(utxo => - mapAddressDataToUtxo(wallet, addressData, utxo) - ) - // remove old utxos - this.utxos.data = this.utxos.data.filter( - u => u.address !== addressData.address - ) - // add new utxos - this.utxos.data.push(...newUtxos) - if (utxos.length) { - this.utxos.data.sort((a, b) => b.sort - a.sort) - this.utxos.total = this.utxos.data.reduce( - (total, y) => (total += y?.amount || 0), - 0 - ) - } - const addressTotal = utxos.reduce( - (total, y) => (total += y?.value || 0), - 0 - ) - this.updateAmountForAddress(addressData, addressTotal) - }, //################### MEMPOOL API ################### getAddressTxsDelayed: async function (addrData) { @@ -370,12 +205,7 @@ window.app = Vue.createApp({ this.tab = tab this[`${tab}Filter`] = value }, - - updateAccounts: async function (accounts) { - this.walletAccounts = accounts - await this.refreshAddresses() - await this.scanAddressWithAmount() - }, + showAddressDetails: function (addressData) { this.openQrCodeDialog(addressData) }, @@ -403,32 +233,17 @@ window.app = Vue.createApp({ if (!this.fetchedUtxos && addresses.length) { this.fetchedUtxos = true this.addresses = addresses - this.scanAddressWithAmount() + // this.scanAddressWithAmount() } }, handleBroadcastSuccess: async function (txId) { this.tab = 'history' this.searchInTab({tab: 'history', value: txId}) this.showPayment = false - await this.refreshAddresses() - await this.scanAddressWithAmount() - }, - handleDeviceConnected: async function (deviceType) { - this.connectedDeviceType = deviceType - } + // await this.refreshAddresses() + // await this.scanAddressWithAmount() + }, }, - created: async function () { - if (this.g.user.wallets.length) { - await this.refreshAddresses() - await this.scanAddressWithAmount() - } - - await TrezorConnect.init({ - lazyLoad: true, // this param will prevent iframe injection until TrezorConnect.method will be called - manifest: { - email: 'vlad@lnbits.com', - appUrl: 'http://lnbits.com' - } - }) + created: async function () { } }) diff --git a/templates/silnt/components/utxo-list.html b/templates/silnt/components/utxo-list.html index 1ae3aea..05f9571 100644 --- a/templates/silnt/components/utxo-list.html +++ b/templates/silnt/components/utxo-list.html @@ -22,94 +22,83 @@ >
-
-
- - - -
+
+ + + +
+ + Unspent: + + + Spent: +
- + + + \ No newline at end of file diff --git a/templates/silnt/components/wallet-config.html b/templates/silnt/components/wallet-config.html index 66abe35..2511d9b 100644 --- a/templates/silnt/components/wallet-config.html +++ b/templates/silnt/components/wallet-config.html @@ -4,12 +4,7 @@
-
-
-
-
${satBtc(total)}
-
-
+ @@ -19,23 +14,39 @@ - + + +
Update @@ -46,4 +57,4 @@ -
+ \ No newline at end of file diff --git a/templates/silnt/index.html b/templates/silnt/index.html index 303451c..c558578 100644 --- a/templates/silnt/index.html +++ b/templates/silnt/index.html @@ -22,13 +22,30 @@ +
+
+ +
+
+ +
+
+ +
+
Scan Blockchain @@ -96,36 +113,10 @@ - - - + - - - - - - - - + {% include "silnt/_api_docs.html" %} -
- - -
Address Details
-
- - - - -

- - - -

-

- -

-
- Gap limit of 20 addresses exceeded. Other wallets might not detect - funds at this address. -
-
- Save Note - Close -
-
-
-
+
@@ -264,30 +194,30 @@
Enter the Signed PSBT
{% endblock %} {% block vue_templates %} - +> --> - +> --> - - {% include("silnt/components/utxo-list.html") %} {% include("silnt/components/wallet-list.html") %} {% endblock %} {% block scripts %} {{ window_vars(user) }} From 448812ff0d284da91185c275b787065750b4aea7 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Fri, 10 Apr 2026 01:13:04 +0100 Subject: [PATCH 38/83] static changes --- templates/silnt/index.html | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/templates/silnt/index.html b/templates/silnt/index.html index 05631fd..8df13d0 100644 --- a/templates/silnt/index.html +++ b/templates/silnt/index.html @@ -460,16 +460,16 @@
Confirm Broadcast
- - - - + + + + - - - - - + + + + + {% endblock %} From b7ce47ffc8f14e11b598185476af7449f0cf3888 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Fri, 10 Apr 2026 01:31:58 +0100 Subject: [PATCH 39/83] silnt static --- templates/silnt/index.html | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/templates/silnt/index.html b/templates/silnt/index.html index 8df13d0..af3edcf 100644 --- a/templates/silnt/index.html +++ b/templates/silnt/index.html @@ -460,16 +460,16 @@
Confirm Broadcast
- - - - + + + + - - - - - + + + + + {% endblock %} From 45b72aa9227b3186c60acbc43024adb61864e7bb Mon Sep 17 00:00:00 2001 From: Ponthief Date: Fri, 10 Apr 2026 15:10:00 +0100 Subject: [PATCH 40/83] static file fixes --- README.md | 8 ++++---- __init__.py | 6 +++--- config.json | 2 +- templates/silnt/index.html | 18 +++++++++--------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index aff340a..812ab6e 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ A [LNbits](https://lnbits.com) extension for managing [Silent Payment](https://s Before scanning, an admin must configure the BlindBit connection via the **Settings** button (⚙️) in the extension UI, or via the API: ```bash -curl -X PUT https:///silnt/api/v1/blindbit/config \ +curl -X PUT https:///siLNt/api/v1/blindbit/config \ -H "X-Api-Key: " \ -H "Content-Type: application/json" \ -d '{ @@ -81,7 +81,7 @@ Click **Send** to open the Send Payment flow. Select UTXOs as inputs, specify re ## API Reference -All endpoints are prefixed with `/silnt/api/v1`. Authentication uses the `X-Api-Key` header. +All endpoints are prefixed with `/siLNt/api/v1`. Authentication uses the `X-Api-Key` header. ### Wallets @@ -107,7 +107,7 @@ All endpoints are prefixed with `/silnt/api/v1`. Authentication uses the `X-Api- | `POST` | `/scan` | Invoice Key | Proxy scan to BlindBit, returns UTXOs and height | -Full interactive docs available at `/docs#/silnt` on your LNbits instance. +Full interactive docs available at `/docs#/siLNt` on your LNbits instance. --- @@ -168,7 +168,7 @@ Full interactive docs available at `/docs#/silnt` on your LNbits instance. ## Project Structure ``` -silnt/ +siLNt/ ├── __init__.py ├── views.py # Page routes ├── views_api.py # REST API endpoints diff --git a/__init__.py b/__init__.py index f8270d0..c536807 100644 --- a/__init__.py +++ b/__init__.py @@ -6,11 +6,11 @@ from .views import silnt_generic_router from .views_api import silnt_api_router -silnt_static_files = [ +siLNt_static_files = [ { "path": "/siLNt/static", "app": StaticFiles(packages=[("lnbits", "extensions/siLNt/static")]), - "name": "silnt_static", + "name": "siLNt_static", } ] @@ -18,4 +18,4 @@ siLNt_ext.include_router(silnt_generic_router) siLNt_ext.include_router(silnt_api_router) -__all__ = ["siLNt_ext", "silnt_static_files", "db"] +__all__ = ["siLNt_ext", "siLNt_static_files", "db"] diff --git a/config.json b/config.json index a71f50b..e502f18 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "name": "BitSiLNt", "short_description": "Silent Payments OnChain Wallet", - "tile": "/silnt/static/bitcoin-wallet.webp", + "tile": "/siLNt/static/bitcoin-wallet.webp", "min_lnbits_version": "v1.4.1", "donate": "satoshi@bitaurus.net", "contributors": [ diff --git a/templates/silnt/index.html b/templates/silnt/index.html index af3edcf..2e8b3ed 100644 --- a/templates/silnt/index.html +++ b/templates/silnt/index.html @@ -460,16 +460,16 @@
Confirm Broadcast
- - - - + + + + - - - - - + + + + + {% endblock %} From 2dde7a6b6edd749d2fb7d174a5ad25b5ff45e199 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Sun, 12 Apr 2026 11:48:41 +0100 Subject: [PATCH 41/83] configure localhost mempool --- models.py | 4 +- static/components/wallet-config.js | 14 +++++-- static/components/wallet-list.js | 14 +++---- static/js/index.js | 39 ++++++++++++------- templates/silnt/_api_docs.html | 2 +- templates/silnt/components/utxo-list.html | 2 +- templates/silnt/components/wallet-config.html | 10 ++++- templates/silnt/index.html | 2 +- views_api.py | 6 ++- 9 files changed, 59 insertions(+), 34 deletions(-) diff --git a/models.py b/models.py index 4acd6ad..67c61cc 100644 --- a/models.py +++ b/models.py @@ -6,6 +6,7 @@ class BlindbitConfig(BaseModel): blindbit_url: str = "" + mempool_url: str = "https://mempool.space" class CreateWallet(BaseModel): @@ -62,8 +63,7 @@ class BroadcastTxRequest(BaseModel): spent_txids: list[str] = [] -class Config(BaseModel): - mempool_endpoint: str = "https://mempool.space" +class Config(BaseModel): sats_denominated: bool = True network: str = "mainnet" diff --git a/static/components/wallet-config.js b/static/components/wallet-config.js index 3e7b5d5..0bfc916 100644 --- a/static/components/wallet-config.js +++ b/static/components/wallet-config.js @@ -20,7 +20,8 @@ window.app.component('wallet-config', { }, set(value) { value.isLoaded = true - value.blindbit_url = value.blindbit_url || '' + value.blindbit_url = value.blindbit_url || '' + value.mempool_url = value.mempool_url || 'https://mempool.space' this.internalConfig = JSON.parse(JSON.stringify(value)) this.$emit( 'update:config-data', @@ -41,7 +42,11 @@ window.app.component('wallet-config', { this.config ) this.show = false - this.config = data + this.config = { + ...this.internalConfig, + ...data, + mempool_url: data.mempool_url || this.internalConfig.mempool_url || 'https://mempool.space' + } } catch (error) { LNbits.utils.notifyApiError(error) } @@ -54,8 +59,9 @@ window.app.component('wallet-config', { ]) this.config = { ...blindbit, - ...appConfig - } + ...appConfig, + mempool_url: blindbit.mempool_url || 'https://mempool.space' + } } catch (error) { LNbits.utils.notifyApiError(error) } diff --git a/static/components/wallet-list.js b/static/components/wallet-list.js index 8e42fed..328ff47 100644 --- a/static/components/wallet-list.js +++ b/static/components/wallet-list.js @@ -7,7 +7,7 @@ window.app.component('wallet-list', { 'adminkey', 'inkey', 'sats-denominated', - 'addresses', + // 'addresses', 'network', 'scannedUtxos' ], @@ -278,12 +278,12 @@ window.app.component('wallet-list', { return false } }, - getBalanceForWallet: function (walletId) { - const amount = this.addresses - .filter(a => a.wallet === walletId) - .reduce((t, a) => t + a.amount || 0, 0) - return this.satBtc(amount) - }, + // getBalanceForWallet: function (walletId) { + // const amount = this.addresses + // .filter(a => a.wallet === walletId) + // .reduce((t, a) => t + a.amount || 0, 0) + // return this.satBtc(amount) + // }, closeFormDialog: function () { this.formDialog.data = { hr_address: '', // ← empty string not null diff --git a/static/js/index.js b/static/js/index.js index 16fa3e6..7c10392 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -66,24 +66,33 @@ window.app = Vue.createApp({ const hasFee = this.sendForm.feeRate > 0 return hasRecipient && hasUtxos && hasAmount && hasFee && !this.sendLoading }, - mempoolHostname: function () { - if (!this.config || !this.config.isLoaded) return 'mempool.space' + mempoolBaseUrl: function () { + if (!this.config || !this.config.isLoaded) return 'https://mempool.space' try { - const endpoint = this.config.mempool_endpoint || 'https://mempool.space' - let hostname = new URL(endpoint).hostname - if ((this.config.network || '').toLowerCase() === 'testnet') { - hostname += '/testnet' - } - return hostname - } catch (e) { - return 'mempool.space' - } - }, + const endpoint = this.config.mempool_url || 'https://mempool.space' + const withProtocol = endpoint.startsWith('http') + ? endpoint + : `https://${endpoint}` + const url = new URL(withProtocol) + let base = `${url.protocol}//${url.hostname}` + if (url.port) base += `:${url.port}` + return base.replace(/\/$/, '') + } catch (e) { + return 'https://mempool.space' + } + }, + // mempoolHostname: function () { + // try { + // const url = new URL(this.mempoolBaseUrl) + // console.log(url.host + (url.pathname !== '/' ? url.pathname : '')) + // return url.host + (url.pathname !== '/' ? url.pathname : '') + // } catch (e) { + // return 'mempool.space' + // } + // }, }, methods: { - - //################### UTXOs ################### fetchUtxos: async function (wallet) { if (!wallet || !wallet.id) return try { @@ -387,7 +396,7 @@ window.app = Vue.createApp({ ) const txid = data.txid - const mempoolUrl = `https://${this.mempoolHostname}/tx/${txid}` + const mempoolUrl = `${this.mempoolBaseUrl}/tx/${txid}` // Mark unconfirmed_spent UTXOs in the local list const selectedTxids = this.sendUtxos .filter(u => u.selected) diff --git a/templates/silnt/_api_docs.html b/templates/silnt/_api_docs.html index 379a4f9..62c6f77 100644 --- a/templates/silnt/_api_docs.html +++ b/templates/silnt/_api_docs.html @@ -378,7 +378,7 @@
Headers
{"X-Api-Key": <invoice_key>}
Returns 200 OK (application/json)
{"mempool_endpoint": <string>, "sats_denominated": <boolean>, + >{"mempool_url": <string>, "sats_denominated": <boolean>, "network": <string>}
Curl example
diff --git a/templates/silnt/components/utxo-list.html b/templates/silnt/components/utxo-list.html index f138be3..072a019 100644 --- a/templates/silnt/components/utxo-list.html +++ b/templates/silnt/components/utxo-list.html @@ -134,7 +134,7 @@
diff --git a/templates/silnt/components/wallet-config.html b/templates/silnt/components/wallet-config.html index 94736c5..3b6b084 100644 --- a/templates/silnt/components/wallet-config.html +++ b/templates/silnt/components/wallet-config.html @@ -21,7 +21,15 @@ type="text" label="BlindBit Oracle URL" > - + +
diff --git a/views_api.py b/views_api.py index d99e4dd..ba27b7d 100644 --- a/views_api.py +++ b/views_api.py @@ -394,8 +394,9 @@ async def api_build_transaction(data: BuildTxRequest): ) async def api_broadcast_transaction(data: BroadcastTxRequest): try: + blindbit = await get_blindbit_config() config = Config() - base = config.mempool_endpoint.rstrip("/") + base = (blindbit.mempool_url or "https://mempool.space" ).rstrip("/") mempool_url = f"{base}/api/tx" async with httpx.AsyncClient(timeout=30.0) as client: @@ -431,9 +432,10 @@ async def api_broadcast_transaction(data: BroadcastTxRequest): async def api_get_config( key_info: WalletTypeInfo = Depends(require_invoice_key), ) -> dict: + blindbit = await get_blindbit_config() config = Config() return { - "mempool_endpoint": config.mempool_endpoint, + "mempool_endpoint": blindbit.mempool_url or "https://mempool.space", "sats_denominated": config.sats_denominated, "network": config.network, } From 73dbf12e9ddb9300afca3a4ebd4d364bb39967fe Mon Sep 17 00:00:00 2001 From: Ponthief Date: Wed, 22 Apr 2026 23:48:34 +0100 Subject: [PATCH 42/83] add support for more than 1 SP address --- crud.py | 43 ++++- helpers/wallet.py | 44 +++++ migrations.py | 11 ++ models.py | 13 ++ static/components/wallet-list.js | 108 ++++++++++- templates/silnt/components/wallet-list.html | 197 ++++++++++++-------- templates/silnt/index.html | 3 +- views_api.py | 107 ++++++++++- 8 files changed, 432 insertions(+), 94 deletions(-) diff --git a/crud.py b/crud.py index 3945a6b..384d2c2 100644 --- a/crud.py +++ b/crud.py @@ -1,9 +1,10 @@ import json +import time from typing import Optional, Tuple import secrets from lnbits.db import Database from lnbits.helpers import urlsafe_short_hash -from .models import Config, BlindbitConfig, WalletAccount, UTXORecord +from .models import Config, BlindbitConfig, WalletAccount, UTXORecord, WalletAddress from embit.descriptor import Descriptor, Key from embit.descriptor.arguments import AllowedDerivation @@ -177,6 +178,46 @@ async def update_unconfirmed_utxo(wallet_id: str, txid: str): {"txid": txid, "wallet_id": wallet_id} ) +async def get_wallet_addresses(wallet_id: str) -> list: + return await db.fetchall( + "SELECT * FROM silnt.wallet_addresses WHERE wallet_id = :wallet_id ORDER BY label_index ASC", + {"wallet_id": wallet_id}, + ) + +async def count_wallet_addresses(wallet_id: str) -> int: + row = await db.fetchone( + "SELECT COUNT(*) as cnt FROM silnt.wallet_addresses WHERE wallet_id = :wallet_id", + {"wallet_id": wallet_id}, + ) + return row["cnt"] if row else 0 + +async def insert_wallet_address(wallet_id: str, sp_address: str, label_index: int, address_id) -> None: + await db.execute( + """INSERT INTO silnt.wallet_addresses (id, wallet_id, sp_address, label_index, created_at) + VALUES (:id, :wallet_id, :sp_address, :label_index, :created_at)""", + { + "id": address_id, + "wallet_id": wallet_id, + "sp_address": sp_address, + "label_index": label_index, + "created_at": int(time.time()) + } + ) + + + +async def delete_wallet_addresses(wallet_id: str) -> None: + await db.execute( + "DELETE FROM silnt.wallet_addresses WHERE wallet_id = :wallet_id", + {"wallet_id": wallet_id}, + ) + +async def delete_wallet_address(address_id: str, wallet_id: str) -> None: + await db.execute( + "DELETE FROM silnt.wallet_addresses WHERE id = :id AND wallet_id = :wallet_id", + {"id": address_id, "wallet_id": wallet_id}, + ) + # ── Global admin-only blindbit config ─────────────────────────────────────── diff --git a/helpers/wallet.py b/helpers/wallet.py index f5f39eb..1a03388 100644 --- a/helpers/wallet.py +++ b/helpers/wallet.py @@ -494,3 +494,47 @@ def taproot_sighash( + input_index.to_bytes(4, "little") # input_index ) return tagged_hash("TapSighash", preimage) + +def generate_labeled_sp_address( + scan_secret_hex: str, + spend_pub_hex: str, + m: int, + hrp: str = 'sp' +) -> str: + """ + Derive a BIP352 labeled Silent Payment address. + B_m = B_spend + hash(b_scan || m) * G + m=0 is reserved for change, user labels start at m=1 + """ + + scan_secret_bytes = bytes.fromhex(scan_secret_hex) + spend_pub_bytes = bytes.fromhex(spend_pub_hex) + + # hash("BIP0352/Label" || b_scan || m) + tag = b"BIP0352/Label" + tag_hash = hashlib.sha256(tag).digest() + label_hash = hashlib.sha256( + tag_hash + tag_hash + scan_secret_bytes + m.to_bytes(4, 'little') + ).digest() + + # B_m = B_spend + label_hash * G + label_point = coincurve.PublicKey.from_secret(label_hash) + spend_pub = coincurve.PublicKey(spend_pub_bytes) + B_m = coincurve.PublicKey.combine_keys([spend_pub, label_point]) + B_m_bytes = B_m.format(compressed=True) + + # Encode as SP address: B_scan || B_m + B_scan = coincurve.PublicKey.from_secret(scan_secret_bytes).format(compressed=True) + + address = bech32_encode( + hrp, + [0] + convertbits(B_scan + B_m_bytes, 8, 5), + Encoding.BECH32M + ) + return address + + +def get_spend_pub_from_secret(spend_secret_hex: str) -> str: + """Derive compressed spend public key from spend private key hex.""" + pub = coincurve.PublicKey.from_secret(bytes.fromhex(spend_secret_hex)) + return pub.format(compressed=True).hex() \ No newline at end of file diff --git a/migrations.py b/migrations.py index 2e10a13..8c4ff40 100644 --- a/migrations.py +++ b/migrations.py @@ -49,3 +49,14 @@ async def m001_initial(db): CREATE UNIQUE INDEX IF NOT EXISTS idx_silnt_utxos_vout ON silnt.utxos (txid, vout); """ ) + +async def m002_subaccounts(db): + await db.execute(""" + CREATE TABLE IF NOT EXISTS silnt.wallet_addresses ( + sp_address TEXT PRIMARY KEY, + id TEXT NOT NULL, + wallet_id TEXT NOT NULL, + label_index INTEGER NOT NULL, + created_at INTEGER NOT NULL DEFAULT 0 + ) + """) \ No newline at end of file diff --git a/models.py b/models.py index 67c61cc..ccf4712 100644 --- a/models.py +++ b/models.py @@ -67,3 +67,16 @@ class Config(BaseModel): sats_denominated: bool = True network: str = "mainnet" +class WalletAddress(BaseModel): + id: str + wallet_id: str + sp_address: str + label_index: int + created_at: int = 0 + +class PreviewAddressRequest(BaseModel): + label_index: int + +class SaveAddressRequest(BaseModel): + sp_address: str + label_index: int \ No newline at end of file diff --git a/static/components/wallet-list.js b/static/components/wallet-list.js index 328ff47..686f430 100644 --- a/static/components/wallet-list.js +++ b/static/components/wallet-list.js @@ -36,6 +36,12 @@ window.app.component('wallet-list', { show: false, address: '' }, + addressDialog: { + show: false, + wallet: null, + addresses: [], + generating: false + }, bip353Valid: true, showCreating: false, showUpdating: false, @@ -206,7 +212,6 @@ window.app.component('wallet-list', { } }) }, -// ?network=${this.network} getsiLNtWallets: async function () { try { const {data} = await LNbits.api.request( @@ -228,7 +233,12 @@ window.app.component('wallet-list', { refreshWalletAccounts: async function () { this.walletAccounts = [] const wallets = await this.getsiLNtWallets() - this.walletAccounts = wallets.map(w => mapWalletAccount(w)) + this.walletAccounts = wallets.map(w => ({ + ...mapWalletAccount(w), + expanded: false, + addresses: [], + loadingAddresses: false + })) this.$emit('accounts-update', this.walletAccounts) }, updateWalletBalance: async function (walletId, balance) { @@ -278,12 +288,94 @@ window.app.component('wallet-list', { return false } }, - // getBalanceForWallet: function (walletId) { - // const amount = this.addresses - // .filter(a => a.wallet === walletId) - // .reduce((t, a) => t + a.amount || 0, 0) - // return this.satBtc(amount) - // }, + toggleAddresses: async function (wallet) { + wallet.expanded = !wallet.expanded + if (wallet.expanded && !wallet.addresses.length) { + wallet.loadingAddresses = true + try { + const {data} = await LNbits.api.request( + 'GET', + `/siLNt/api/v1/wallet/${wallet.id}/addresses`, + this.inkey + ) + wallet.addresses = data.addresses || [] + } catch (error) { + LNbits.utils.notifyApiError(error) + } finally { + wallet.loadingAddresses = false + } + } + }, + generateAddress: async function (wallet) { + const rw = this.walletAccounts.find(w => w.id === wallet.id) + if (!rw) return + + if ((rw.addresses || []).length >= 10) { + this.$q.notify({ type: 'warning', message: 'Maximum of 10 labeled addresses per wallet reached.', timeout: 5000 }) + return + } + + const currentAddresses = rw.addresses || [] + const existingMax = currentAddresses.reduce((max, a) => Math.max(max, a.label_index || 0), 0) + const nextIndex = existingMax + 1 + + try { + const {data} = await LNbits.api.request( + 'POST', + `/siLNt/api/v1/wallet/${rw.id}/addresses/preview`, + this.inkey, + { label_index: nextIndex } + ) + rw.addresses = [...currentAddresses, { + _tempId: Date.now(), + id: null, + wallet_id: rw.id, + sp_address: data.sp_address, + label_index: nextIndex, + saved: false + }] + } catch (error) { + LNbits.utils.notifyApiError(error) + } + }, + + saveAddress: async function (wallet, addr) { + const rw = this.walletAccounts.find(w => w.id === wallet.id) + if (!rw) return + try { + const {data} = await LNbits.api.request('POST', `/siLNt/api/v1/wallet/${rw.id}/addresses`, this.inkey, { + sp_address: addr.sp_address, + label_index: addr.label_index + }) + const idx = rw.addresses.findIndex(a => a._tempId === addr._tempId) + if (idx !== -1) rw.addresses.splice(idx, 1, { ...data, saved: true }) + Quasar.Notify.create({ type: 'positive', message: 'Address saved.' }) + } catch (error) { + LNbits.utils.notifyApiError(error) + } + }, + + deleteAddress: async function (wallet, addr) { + const rw = this.walletAccounts.find(w => w.id === wallet.id) + if (!rw) return + if (!addr.id) { + rw.addresses = rw.addresses.filter(a => a._tempId !== addr._tempId) + return + } + LNbits.utils.confirmDialog('Delete this labeled address?').onOk(async () => { + try { + await LNbits.api.request('DELETE', `/siLNt/api/v1/wallet/${rw.id}/addresses/${addr.id}`, this.inkey) + rw.addresses = rw.addresses.filter(a => a.id !== addr.id) + Quasar.Notify.create({ type: 'positive', message: 'Address deleted.' }) + } catch (error) { + LNbits.utils.notifyApiError(error) + } + }) + }, + showQrCodeAddress: function (address) { + this.qrDialog.address = address + this.qrDialog.show = true + }, closeFormDialog: function () { this.formDialog.data = { hr_address: '', // ← empty string not null diff --git a/templates/silnt/components/wallet-list.html b/templates/silnt/components/wallet-list.html index 0e04b61..eef5bb5 100644 --- a/templates/silnt/components/wallet-list.html +++ b/templates/silnt/components/wallet-list.html @@ -56,98 +56,131 @@ @@ -316,4 +349,4 @@
Receive to Silent Payment Address
- + \ No newline at end of file diff --git a/templates/silnt/index.html b/templates/silnt/index.html index 165ec72..82db1a5 100644 --- a/templates/silnt/index.html +++ b/templates/silnt/index.html @@ -89,8 +89,7 @@
- Silent Payments Wallet Extension - (v0.1) + Silent Payments Wallet Extension
diff --git a/views_api.py b/views_api.py index ba27b7d..e749c4c 100644 --- a/views_api.py +++ b/views_api.py @@ -9,6 +9,8 @@ decrypt_spend_key, decrypt_secret, build_transaction, + generate_labeled_sp_address, + get_spend_pub_from_secret ) from .helpers.scan import scan_wallet, get_scan_progress, request_scan_stop from .helpers.address_resolver import bip353_resolve @@ -35,7 +37,11 @@ get_spend_key, get_utxos_for_wallet, insert_utxos_for_wallet, - update_unconfirmed_utxo + update_unconfirmed_utxo, + get_wallet_addresses, + count_wallet_addresses, + insert_wallet_address, + delete_wallet_address ) from .models import ( @@ -46,12 +52,17 @@ BroadcastTxRequest, Config, ScanWalletRequest, + SaveAddressRequest, + PreviewAddressRequest ) +MAX_ADDRESSES_PER_WALLET = 10 + silnt_api_router = APIRouter() + # ── Wallets ────────────────────────────────────────────────────────────────── @@ -199,9 +210,103 @@ async def api_wallet_delete(wallet_id: str): ) await delete_silnt_wallet(wallet_id) await delete_utxos_for_wallet(wallet_id) + await delete_wallet_addresses(wallet_id) return "", HTTPStatus.NO_CONTENT +@silnt_api_router.get("/api/v1/wallet/{wallet_id}/addresses") +async def api_get_wallet_addresses( + wallet_id: str, + key_info: WalletTypeInfo = Depends(require_invoice_key) +): + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + if wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + addresses = await get_wallet_addresses(wallet_id) + return {"addresses": addresses, "max": MAX_ADDRESSES_PER_WALLET} + + +@silnt_api_router.post("/api/v1/wallet/{wallet_id}/addresses/preview") +async def api_preview_wallet_address( + wallet_id: str, + data: PreviewAddressRequest, + key_info: WalletTypeInfo = Depends(require_invoice_key) +): + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + if wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + + scan_secret = await decrypt_secret(wallet.scan_secret) + spend_key_encrypted = await get_spend_key(wallet_id) + spend_key_hex = decrypt_spend_key(spend_key_encrypted, scan_secret) + spend_pub_hex = get_spend_pub_from_secret(spend_key_hex) + hrp = 'sp' + + try: + sp_address = generate_labeled_sp_address( + scan_secret_hex=scan_secret, + spend_pub_hex=spend_pub_hex, + m=data.label_index, + hrp=hrp + ) + except Exception as e: + raise HTTPException( + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + detail=f"Failed to generate address: {str(e)}" + ) + + return { + "sp_address": sp_address, + "label_index": data.label_index, + "wallet_id": wallet_id + } + +@silnt_api_router.delete("/api/v1/wallet/{wallet_id}/addresses/{address_id}") +async def api_delete_wallet_address( + wallet_id: str, + address_id: str, + key_info: WalletTypeInfo = Depends(require_invoice_key) +): + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + if wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + await delete_wallet_address(address_id, wallet_id) + return "", HTTPStatus.NO_CONTENT + + +@silnt_api_router.post("/api/v1/wallet/{wallet_id}/addresses") +async def api_save_generated_wallet_address( + wallet_id: str, + data: SaveAddressRequest, + key_info: WalletTypeInfo = Depends(require_invoice_key) +): + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + if wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + + count = await count_wallet_addresses(wallet_id) + if count >= MAX_ADDRESSES_PER_WALLET: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=f"Maximum of {MAX_ADDRESSES_PER_WALLET} addresses per wallet reached." + ) + addr_id = urlsafe_short_hash() + await insert_wallet_address(wallet_id, data.sp_address, data.label_index, addr_id) + return { + "sp_address": data.sp_address, + "label_index": data.label_index, + "wallet_id": wallet_id, + "id": addr_id + } + @silnt_api_router.get( "/api/v1/oracle/tip", dependencies=[Depends(require_invoice_key)], From e2be454103768a76c5fdac1fab31d8c4a151cf37 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Thu, 23 Apr 2026 08:23:35 +0100 Subject: [PATCH 43/83] load saved subaccounts --- static/components/wallet-list.js | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/static/components/wallet-list.js b/static/components/wallet-list.js index 686f430..f730f77 100644 --- a/static/components/wallet-list.js +++ b/static/components/wallet-list.js @@ -233,12 +233,29 @@ window.app.component('wallet-list', { refreshWalletAccounts: async function () { this.walletAccounts = [] const wallets = await this.getsiLNtWallets() - this.walletAccounts = wallets.map(w => ({ - ...mapWalletAccount(w), - expanded: false, - addresses: [], - loadingAddresses: false - })) + // Load addresses for each wallet in parallel + const walletsWithAddresses = await Promise.all( + wallets.map(async w => { + let addresses = [] + try { + const {data} = await LNbits.api.request( + 'GET', + `/siLNt/api/v1/wallet/${w.id}/addresses`, + this.inkey + ) + addresses = data.addresses || [] + } catch (e) { + // ignore — wallet still loads without addresses + } + return { + ...mapWalletAccount(w), + expanded: false, + addresses: addresses, + loadingAddresses: false + } + }) + ) + this.walletAccounts = walletsWithAddresses this.$emit('accounts-update', this.walletAccounts) }, updateWalletBalance: async function (walletId, balance) { @@ -290,7 +307,7 @@ window.app.component('wallet-list', { }, toggleAddresses: async function (wallet) { wallet.expanded = !wallet.expanded - if (wallet.expanded && !wallet.addresses.length) { + if (wallet.expanded && !wallet.addresses.length && !wallet.loadingAddresses) { wallet.loadingAddresses = true try { const {data} = await LNbits.api.request( From b35d6c00716371c216aca28c976c41678ee3dd9d Mon Sep 17 00:00:00 2001 From: Ponthief Date: Thu, 23 Apr 2026 08:32:12 +0100 Subject: [PATCH 44/83] readme update --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 812ab6e..90c8b9c 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,10 @@ curl -X PUT https:///siLNt/api/v1/blindbit/config \ }' ``` +### Mempool Connection + +Optionaly, Admin user can configure Mempool URL. Default: [Mempool](https://mempool.space) + --- ## Usage @@ -160,7 +164,7 @@ Full interactive docs available at `/docs#/siLNt` on your LNbits instance. ## Security Notes - Mnemonics are **never stored in the database**. They are AES-encrypted client-side before transmission and used only to derive the Silent Payment address, scan key, and spend key at wallet creation time. -- BlindBit credentials are stored server-side and used only for proxied scan requests — they are never returned to the browser in a usable form. +- For added privacy, Mempool URL is configurable and can be set to local instance. - Invoice Key is required for all write operations (wallet creation, config updates, deletions). --- From 6440bcc21c4ce9046df678021c9d72836d1de388 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Thu, 23 Apr 2026 23:31:15 +0100 Subject: [PATCH 45/83] add badge for unsaved sp --- README.md | 2 +- static/components/wallet-list.js | 9 ++++++++- static/js/index.js | 15 +++------------ templates/silnt/components/wallet-list.html | 7 +++++++ 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 90c8b9c..6d80a06 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ Full interactive docs available at `/docs#/siLNt` on your LNbits instance. ## Security Notes - Mnemonics are **never stored in the database**. They are AES-encrypted client-side before transmission and used only to derive the Silent Payment address, scan key, and spend key at wallet creation time. -- For added privacy, Mempool URL is configurable and can be set to local instance. +- For added privacy, Mempool URL should be configured to point to local instance. - Invoice Key is required for all write operations (wallet creation, config updates, deletions). --- diff --git a/static/components/wallet-list.js b/static/components/wallet-list.js index f730f77..6271c47 100644 --- a/static/components/wallet-list.js +++ b/static/components/wallet-list.js @@ -11,7 +11,7 @@ window.app.component('wallet-list', { 'network', 'scannedUtxos' ], - emits: ['accounts-update', 'fetch-utxos', 'scan-wallet', 'clear-utxos', 'open-bip353', 'send-wallet'], + emits: ['accounts-update', 'fetch-utxos', 'scan-wallet', 'clear-utxos', 'open-bip353', 'send-wallet'], data: function () { return { walletAccounts: [], @@ -351,6 +351,7 @@ window.app.component('wallet-list', { label_index: nextIndex, saved: false }] + this.$emit('addresses-changed') } catch (error) { LNbits.utils.notifyApiError(error) } @@ -366,6 +367,7 @@ window.app.component('wallet-list', { }) const idx = rw.addresses.findIndex(a => a._tempId === addr._tempId) if (idx !== -1) rw.addresses.splice(idx, 1, { ...data, saved: true }) + this.$emit('addresses-changed') Quasar.Notify.create({ type: 'positive', message: 'Address saved.' }) } catch (error) { LNbits.utils.notifyApiError(error) @@ -389,6 +391,11 @@ window.app.component('wallet-list', { } }) }, + created: async function () { + if (this.inkey) { + await this.refreshWalletAccounts() + } + }, showQrCodeAddress: function (address) { this.qrDialog.address = address this.qrDialog.show = true diff --git a/static/js/index.js b/static/js/index.js index 7c10392..5c06f8a 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -50,7 +50,7 @@ window.app = Vue.createApp({ }, sendLoading: false, broadcastLoading: false, - sendTxResult: null, + sendTxResult: null } }, computed: { @@ -80,16 +80,7 @@ window.app = Vue.createApp({ } catch (e) { return 'https://mempool.space' } - }, - // mempoolHostname: function () { - // try { - // const url = new URL(this.mempoolBaseUrl) - // console.log(url.host + (url.pathname !== '/' ? url.pathname : '')) - // return url.host + (url.pathname !== '/' ? url.pathname : '') - // } catch (e) { - // return 'mempool.space' - // } - // }, + } }, methods: { @@ -450,7 +441,7 @@ window.app = Vue.createApp({ confirmBroadcast: function () { this.showBroadcastConfirm = true }, - }, + }, created: async function () { } }) diff --git a/templates/silnt/components/wallet-list.html b/templates/silnt/components/wallet-list.html index eef5bb5..e1e6825 100644 --- a/templates/silnt/components/wallet-list.html +++ b/templates/silnt/components/wallet-list.html @@ -69,6 +69,13 @@ class="row items-center no-wrap q-mt-xs" style="border-left: 2px solid #9c27b0; padding-left: 6px" > + unsaved From bf3948212cc2a0502ab9f459108a708aa72ac694 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Fri, 24 Apr 2026 08:41:10 +0100 Subject: [PATCH 46/83] update readme api docs --- README.md | 224 ++++++++++++++++++++++----------- templates/silnt/_api_docs.html | 118 +++++++++++++++-- 2 files changed, 261 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index 6d80a06..3136ead 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SiLNt — Silent Payments Wallet Extension for LNbits -A [LNbits](https://lnbits.com) extension for managing [Silent Payment](https://silentpayments.xyz) Bitcoin wallets, with blockchain scanning powered by [BlindBit-Oracle](https://github.com/setavenger/blindbit-oracle). +A [LNbits](https://lnbits.com) extension for managing [Silent Payment](https://silentpayments.xyz) Bitcoin wallets, with blockchain scanning powered by a self-hosted [BlindBit Oracle](https://github.com/setavenger/blindbit-oracle). --- @@ -8,49 +8,55 @@ A [LNbits](https://lnbits.com) extension for managing [Silent Payment](https://s - Generate Silent Payment addresses from a BIP39 mnemonic - Store and manage multiple Silent Payment wallet accounts per user -- Support for Mainnet only -- Human Readable Address support ([BIP353](https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki) email format) -- Blockchain scanning via a self-hosted BlindBit instance +- Generate up to 10 BIP352 labeled SP subaccount addresses per wallet +- Human Readable Address support ([BIP353](https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki) email format) — validated against SP address on create/update +- Blockchain scanning via a self-hosted BlindBit Oracle with real-time progress tracking and stop/resume - UTXO tracking with automatic balance updates (unspent only) -- Send to another SilentPayment/On-Chain or BIP-353 Address -- Admin-controlled BlindBit connection settings +- Send to Silent Payment, on-chain, or BIP353 email addresses +- Configurable Mempool URL (supports local instances via http or https) +- Admin-controlled BlindBit Oracle connection settings +- QR code display for SP addresses and subaccount addresses --- ## Requirements - LNbits instance (self-hosted) -- Python dependencies: `embit`, `httpx`, `coincurve` +- Python dependencies: `embit`, `httpx`, `coincurve`, `cryptography`, `dnspython`, `ecdsa` - A running [blindbit-oracle](https://github.com/setavenger/blindbit-oracle) instance for blockchain scanning --- ## Installation -1. As Admin user, navigate to Settings -> Extensions and add Source: [Ponthief-Extensions](https://raw.githubusercontent.com/ponthief/lnbits-extensions/extensions/extensions.json). +1. As Admin user, navigate to **Settings → Extensions** and add Source: + [Ponthief-Extensions](https://raw.githubusercontent.com/ponthief/lnbits-extensions/extensions/extensions.json) 2. Install/Enable the extension from the LNbits admin panel under **Extensions**. -3. Run database migrations (handled automatically on first load via LNbits migration system). +3. Database migrations run automatically on first load. --- ## Configuration -### BlindBit Connection +### BlindBit Oracle Connection -Before scanning, an admin must configure the BlindBit connection via the **Settings** button (⚙️) in the extension UI, or via the API: +Before scanning, an admin must configure the BlindBit Oracle connection via the **Settings** button (⚙️) in the extension UI, or via the API: ```bash curl -X PUT https:///siLNt/api/v1/blindbit/config \ -H "X-Api-Key: " \ -H "Content-Type: application/json" \ -d '{ - "blindbit_url": "http://localhost:8001", + "blindbit_url": "http://localhost:8001", + "blindbit_user": "", + "blindbit_pass": "", + "mempool_url": "https://mempool.space" }' ``` -### Mempool Connection +### Mempool URL -Optionaly, Admin user can configure Mempool URL. Default: [Mempool](https://mempool.space) +The Mempool URL is configured alongside the BlindBit Oracle settings. It defaults to `https://mempool.space` but can be pointed to a local Mempool instance for added privacy. Both `http` and `https` are supported. --- @@ -58,28 +64,47 @@ Optionaly, Admin user can configure Mempool URL. Default: [Mempool](https://memp ### 1. Add a Wallet Account -Click **Silent Payments Wallet Account** → **New Wallet Account** and fill in: +Click **Silent Payments Wallet Account → New Wallet Account** and fill in: | Field | Description | |---|---| -| Title | Display name for the wallet | -| Mnemonic | 12-word BIP39 seed phrase (encrypted client-side, never stored in plaintext) | +| Mnemonic | 12-word BIP39 seed phrase (AES-encrypted client-side, never stored) | | Born at Height | Block height of the wallet's first transaction — reduces scan time | -| Human Readable Address | Optional BIP353 email-format address (e.g. `alice@domain.com`) | +| Human Readable Address | Optional BIP353 email-format address (e.g. `alice@domain.com`) — must resolve to this wallet's SP address | -> **Note:** The mnemonic is AES-encrypted using the born-at height as the key before being sent to the server. It is not stored in the database. +> The mnemonic is AES-encrypted using the born-at height as the key before transmission. It is never stored in the database. -### 2. Scan the Blockchain +### 2. Generate Labeled SP Addresses (Subaccounts) -Click **Scan Blockchain** to proxy a scan request through LNbits to your BlindBit instance. The extension fetches: -- All UTXOs associated with the wallet's Silent Payment address -- The current block height +Click **+** on a wallet row to generate a new BIP352 labeled SP address (up to 10 per wallet). Labeled addresses appear inline below the main SP address with an amber border. Click **Save** to persist to the database — unsaved addresses are marked with an `unsaved` badge. -Wallet balance is updated automatically after each scan, counting only **unspent** UTXOs. +### 3. Scan the Blockchain -### 3. Make a Payment +Click the **Bitcoin** icon button on a wallet row to open the scan dialog. The dialog shows: +- **Scan From** — last scanned height (editable) +- **Chain Tip** — fetched live from the Oracle (editable) +- **Blocks to Scan** — calculated automatically -Click **Send** to open the Send Payment flow. Select UTXOs as inputs, specify recipient, and sign the resulting transaction. Click **Broadcast** to broadcast transaction for "mining". +Click **Sync to Tip** to start scanning. A progress bar shows real-time progress. Click **Stop** to pause — progress is saved and the next scan resumes from where it left off. + +### 4. Load UTXOs from DB + +Click the **database** icon button on a wallet row to load previously scanned UTXOs from the local database. + +### 5. Make a Payment + +Click **Send** to open the Send Payment flow: +1. Select UTXOs to spend (checkbox + amount shown) +2. Enter recipient (SP address, on-chain address, or BIP353 email) +3. Set amount and fee rate +4. Click **Build Transaction** — reviews fee before broadcasting +5. Click **Broadcast** → confirm in the confirmation dialog + +After broadcast, selected UTXOs are marked as spent and a Mempool link is shown in the notification. + +### 6. Resolve BIP353 + +Click **Resolve BIP353** to look up a BIP353 email-format address and display the resolved SP address. --- @@ -93,25 +118,61 @@ All endpoints are prefixed with `/siLNt/api/v1`. Authentication uses the `X-Api- |---|---|---|---| | `GET` | `/wallet` | Invoice Key | List all wallet accounts | | `GET` | `/wallet/{wallet_id}` | Invoice Key | Get a wallet account | -| `POST` | `/wallet` | Admin Key | Create a wallet account | -| `PUT` | `/wallet/{wallet_id}` | Admin Key | Update hr_address, last_height| -| `DELETE` | `/wallet/{wallet_id}` | Admin Key | Delete wallet and all its UTXOs | +| `POST` | `/wallet` | Invoice Key | Create a wallet account | +| `PUT` | `/wallet/{wallet_id}` | Invoice Key | Update hr_address, last_height, title, balance | +| `DELETE` | `/wallet/{wallet_id}` | Invoice Key | Delete wallet, UTXOs and labeled addresses | -### BlindBit Config +### Labeled SP Addresses | Method | Endpoint | Auth | Description | |---|---|---|---| -| `GET` | `/blindbit/config` | Invoice Key | Get BlindBit connection settings | -| `PUT` | `/blindbit/config` | Admin Key | Update BlindBit connection settings | +| `GET` | `/wallet/{wallet_id}/addresses` | Invoice Key | List saved labeled SP addresses | +| `POST` | `/wallet/{wallet_id}/addresses/preview` | Invoice Key | Preview a labeled SP address (not saved) | +| `POST` | `/wallet/{wallet_id}/addresses` | Invoice Key | Save a labeled SP address to DB | +| `DELETE` | `/wallet/{wallet_id}/addresses/{address_id}` | Invoice Key | Delete a labeled SP address | ### Scanning | Method | Endpoint | Auth | Description | |---|---|---|---| -| `POST` | `/scan` | Invoice Key | Proxy scan to BlindBit, returns UTXOs and height | +| `POST` | `/wallet/{wallet_id}/scan` | Invoice Key | Scan blockchain for UTXOs | +| `POST` | `/wallet/{wallet_id}/scan/stop` | Invoice Key | Stop an in-progress scan | +| `GET` | `/wallet/{wallet_id}/scan/progress` | Invoice Key | Get real-time scan progress | + +### UTXOs + +| Method | Endpoint | Auth | Description | +|---|---|---|---| +| `GET` | `/utxos?wallet_id=` | Invoice Key | Load UTXOs from DB for a wallet | + +### BlindBit Oracle +| Method | Endpoint | Auth | Description | +|---|---|---|---| +| `GET` | `/blindbit/config` | Invoice Key | Get Oracle connection settings | +| `PUT` | `/blindbit/config` | Admin Key | Update Oracle connection settings incl. Mempool URL | +| `GET` | `/oracle/tip` | Invoice Key | Get current chain tip from Oracle | + +### BIP353 + +| Method | Endpoint | Auth | Description | +|---|---|---|---| +| `GET` | `/bip353/resolve?address=` | Invoice Key | Resolve a BIP353 email-format address | -Full interactive docs available at `/docs#/siLNt` on your LNbits instance. +### Transactions + +| Method | Endpoint | Auth | Description | +|---|---|---|---| +| `POST` | `/tx/build` | Admin Key | Build and sign a transaction | +| `POST` | `/tx/broadcast` | Admin Key | Broadcast a signed transaction | + +### Config + +| Method | Endpoint | Auth | Description | +|---|---|---|---| +| `GET` | `/config` | Invoice Key | Get app config including mempool endpoint | + +Full interactive docs at `/docs#/siLNt` on your LNbits instance. --- @@ -123,39 +184,51 @@ Full interactive docs available at `/docs#/siLNt` on your LNbits instance. { "id": "abc123xyz", "user": "usr_abc123", - "title": "My Silent Wallet", + "title": "sp1qqw...", "balance": 100000, "hr_address": "alice@domain.com", - "network": "Mainnet", + "network": "mainnet", "last_height": 840000, + "last_scan_height": 842000, "sp_address": "sp1qqw..." } ``` +### WalletAddress (Labeled SP) + +```json +{ + "id": "xyz789", + "wallet_id": "abc123xyz", + "sp_address": "sp1qq...", + "label_index": 1, + "created_at": 1710000000 +} +``` + ### BlindbitConfig ```json { - "blindbit_url": "http://localhost:8001" + "blindbit_url": "http://localhost:8001", + "blindbit_user": "", + "blindbit_pass": "", + "mempool_url": "https://mempool.space" } ``` -### ScanResult +### UTXORecord ```json { - "utxos": [ - { - "txid": "a1b2c3...", - "amount": 50000, - "utxo_state": "unspent", - "label": "", - "timestamp": 1710000000 - } - ], - "height": { - "height": 840100 - } + "txid": "a1b2c3...", + "vout": 0, + "amount": 50000, + "priv_key_tweak": "...", + "pub_key": "...", + "timestamp": 1710000000, + "utxo_state": "unspent", + "wallet_id": "abc123xyz" } ``` @@ -163,9 +236,12 @@ Full interactive docs available at `/docs#/siLNt` on your LNbits instance. ## Security Notes -- Mnemonics are **never stored in the database**. They are AES-encrypted client-side before transmission and used only to derive the Silent Payment address, scan key, and spend key at wallet creation time. -- For added privacy, Mempool URL should be configured to point to local instance. -- Invoice Key is required for all write operations (wallet creation, config updates, deletions). +- Mnemonics are **never stored**. AES-encrypted client-side before transmission, used only to derive keys at creation time. +- The `scan_secret` (scan private key) is encrypted at rest using a server-side Fernet key. +- The `spend_key` is encrypted at rest using the `scan_secret` as the AES key — double-layered protection. +- BIP353 `hr_address` is validated server-side on create and update — it must resolve to the wallet's SP address. +- Configure `mempool_url` to point to a local Mempool instance for transaction broadcasting privacy. +- Admin Key is required for all write operations that affect funds (tx build, broadcast, BlindBit config). --- @@ -174,25 +250,27 @@ Full interactive docs available at `/docs#/siLNt` on your LNbits instance. ``` siLNt/ ├── __init__.py -├── views.py # Page routes -├── views_api.py # REST API endpoints -├── crud.py # Database operations -├── models.py # Pydantic models -├── migrations.py # DB schema migrations +├── views.py # Page routes +├── views_api.py # REST API endpoints +├── crud.py # Database operations +├── models.py # Pydantic models +├── migrations.py # DB schema migrations ├── helpers/ -│ └── wallet.py # Silent Payment address derivation, mnemonic decryption +│ ├── wallet.py # SP address derivation, key encryption, tx building +│ ├── scan.py # Blockchain scanner (BlindBit Oracle client) +│ ├── address_resolver.py # BIP353 DNS resolution +│ └── curve.py # secp256k1 EC math helpers ├── static/ │ ├── js/ -│ │ ├── index.js # Main Vue app -│ │ ├── tables.js # Table definitions -│ │ ├── map.js # Data mapping functions -│ │ └── utils.js # Utility functions +│ │ ├── index.js # Main Vue app +│ │ ├── tables.js # Table column definitions +│ │ ├── map.js # Data mapping functions +│ │ ├── utils.js # Utility functions +│ │ └── bip39-word-list.js # BIP39 word list for mnemonic validation │ └── components/ -│ ├── wallet-config.js / .html -│ ├── wallet-list.js / .html -│ ├── utxo-list.js / .html -│ ├── payment.js / .html -│ └── send-to.js / .html +│ ├── wallet-config.js / .html # BlindBit Oracle settings +│ ├── wallet-list.js / .html # Wallet table with labeled addresses +│ └── utxo-list.js / .html # UTXO table └── templates/ └── silnt/ ├── index.html @@ -200,9 +278,15 @@ siLNt/ ``` --- + ## References -[BIP353 Light Client Specifications](https://github.com/setavenger/BIP0352-light-client-specification) +- [BIP352 — Silent Payments](https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki) +- [BIP353 — DNS Payment Instructions](https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki) +- [BIP352 Light Client Specification](https://github.com/setavenger/BIP0352-light-client-specification) +- [BlindBit Oracle](https://github.com/setavenger/blindbit-oracle) + +--- ## Contributing @@ -212,7 +296,7 @@ Pull requests welcome. Please open an issue first to discuss significant changes ## Author -Created by [Ponthief](https://github.com/ponthief) +Created by [Ponthief](https://github.com/ponthief) at [Bitaurus](https://bitaurus.net) --- diff --git a/templates/silnt/_api_docs.html b/templates/silnt/_api_docs.html index 62c6f77..260c816 100644 --- a/templates/silnt/_api_docs.html +++ b/templates/silnt/_api_docs.html @@ -7,7 +7,7 @@

- BitsiLNt
+ SiLNt
Created by:
Usage
- 1. Configure BlindBit Oracle URL via the settings button (admin only)
+ 1. Configure BlindBit Oracle URL and optional Mempool URL via the settings button (admin only)
2. Add a Silent Payment wallet account using a 12-word BIP39 mnemonic
3. Set the block height of your wallet's first transaction (born-at height)
- 4. Optionally add a Human Readable Address (BIP353 email format)
+ 4. Optionally add a Human Readable Address (BIP353 email format — validated against SP address)
5. Click the scan button on the wallet row to scan the blockchain for UTXOs
6. Click the database button to load already-scanned UTXOs from the DB
7. Wallet balance updates automatically after each scan (unspent UTXOs only)
8. Use the Send button to build and broadcast a Bitcoin transaction
+ 9. Generate up to 10 labeled SP subaccount addresses per wallet

@@ -91,6 +92,8 @@
Body (application/json)
"hr_address": <string>, "last_height": <string>, "network": "mainnet" | "testnet"} +
Notes
+ If hr_address is provided, it must resolve via BIP353 DNS to this wallet's SP address.
Returns 200 OK (application/json)
""
Curl example
@@ -114,6 +117,8 @@
Body (application/json)
>{"hr_address": <string>, "last_height": <string>, "title": <string>, "balance": <integer>} +
Notes
+ If hr_address is updated, it must resolve via BIP353 DNS to this wallet's SP address.
Returns 200 OK (application/json)
""
Curl example
@@ -132,6 +137,8 @@
Curl example
DELETE /siLNt/api/v1/wallet/{wallet_id}
Headers
{"X-Api-Key": <invoice_key>}
+
Notes
+ Also deletes all UTXOs and labeled SP addresses for this wallet.
Returns 204 No Content
Curl example
Curl example
+ + + + + + GET /siLNt/api/v1/wallet/{wallet_id}/addresses +
Headers
+ {"X-Api-Key": <invoice_key>}
+
Returns 200 OK (application/json)
+ {"addresses": [<address_object>, ...], "max": 10} +
Curl example
+ curl -X GET {{ request.base_url }}siLNt/api/v1/wallet/<wallet_id>/addresses -H + "X-Api-Key: <invoice_key>" + +
+
+
+ + + + + POST /siLNt/api/v1/wallet/{wallet_id}/addresses/preview +
Headers
+ {"X-Api-Key": <invoice_key>}
+
Body (application/json)
+ {"label_index": <integer>} +
Notes
+ Derives a BIP352 labeled SP address without saving to DB. label_index starts at 1 (0 is reserved for change). +
Returns 200 OK (application/json)
+ {"sp_address": <string>, "label_index": <integer>, "wallet_id": <string>} +
Curl example
+ curl -X POST {{ request.base_url }}siLNt/api/v1/wallet/<wallet_id>/addresses/preview -H + "X-Api-Key: <invoice_key>" -H "Content-Type: application/json" -d + '{"label_index": 1}' + +
+
+
+ + + + + POST /siLNt/api/v1/wallet/{wallet_id}/addresses +
Headers
+ {"X-Api-Key": <invoice_key>}
+
Body (application/json)
+ {"sp_address": <string>, "label_index": <integer>} +
Notes
+ Persists a previously previewed labeled SP address to the DB. Maximum 10 per wallet. +
Returns 200 OK (application/json)
+ {"sp_address": <string>, "label_index": <integer>, "wallet_id": <string>, "id": <string>} +
Curl example
+ curl -X POST {{ request.base_url }}siLNt/api/v1/wallet/<wallet_id>/addresses -H + "X-Api-Key: <invoice_key>" -H "Content-Type: application/json" -d + '{"sp_address": "sp1qq...", "label_index": 1}' + +
+
+
+ + + + + DELETE /siLNt/api/v1/wallet/{wallet_id}/addresses/{address_id} +
Headers
+ {"X-Api-Key": <invoice_key>}
+
Returns 204 No Content
+
Curl example
+ curl -X DELETE {{ request.base_url }}siLNt/api/v1/wallet/<wallet_id>/addresses/<address_id> -H + "X-Api-Key: <invoice_key>" + +
+
+
+ @@ -236,7 +322,7 @@
Headers
Returns 200 OK (application/json)
{"blindbit_url": <string>, "blindbit_user": <string>, - "blindbit_pass": <string>}
Curl example
Headers
Body (application/json)
{"blindbit_url": <string>, "blindbit_user": <string>, - "blindbit_pass": <string>} +
Notes
+ mempool_url defaults to https://mempool.space if not provided. Supports both http and https.
Returns 200 OK (application/json)
{"blindbit_url": <string>, "blindbit_user": <string>, - "blindbit_pass": <string>}
Curl example
curl -X PUT {{ request.base_url }}siLNt/api/v1/blindbit/config -H "X-Api-Key: <admin_key>" -H "Content-Type: application/json" -d - '{"blindbit_url": "https://localhost:8001", "blindbit_user": "user", - "blindbit_pass": "pass"}' + '{"blindbit_url": "http://localhost:8001", "mempool_url": "http://localhost:8080"}' @@ -331,6 +418,8 @@
Body (application/json)
"amount": <integer>, "vout": <integer>, "priv_key_tweak": <string>, "pub_key": <string>}]}
+
Notes
+ recipient can be a Silent Payment address (sp1...), on-chain address, or BIP353 email address. BIP353 addresses are auto-resolved server-side.
Returns 200 OK (application/json)
{"tx_hex": <string>, "fee": <integer>, @@ -355,14 +444,19 @@
Curl example
Headers
{"X-Api-Key": <admin_key>}
Body (application/json)
- {"tx_hex": <string>} + {"tx_hex": <string>, "wallet_id": <string>, + "spent_txids": [<string>, ...]} +
Notes
+ Broadcasts to configured Mempool URL. spent_txids are marked as unconfirmed_spent in the DB.
Returns 200 OK (application/json)
{"txid": <string>}
Curl example
curl -X POST {{ request.base_url }}siLNt/api/v1/tx/broadcast -H "X-Api-Key: <admin_key>" -H "Content-Type: application/json" -d - '{"tx_hex": "0200000001..."}' + '{"tx_hex": "0200000001...", "wallet_id": "...", "spent_txids": ["..."]}' @@ -376,9 +470,11 @@
Curl example
GET /siLNt/api/v1/config
Headers
{"X-Api-Key": <invoice_key>}
+
Notes
+ Returns mempool_endpoint from BlindBit config (falls back to https://mempool.space).
Returns 200 OK (application/json)
{"mempool_url": <string>, "sats_denominated": <boolean>, + >{"mempool_endpoint": <string>, "sats_denominated": <boolean>, "network": <string>}
Curl example
From 283043d7ebd959bcc112072644dfa46a9235bd12 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Wed, 29 Apr 2026 11:45:29 +0100 Subject: [PATCH 47/83] support for Blindbit Oracle v2 --- helpers/scan.py | 405 +++++++++++++++++++++++++++++++-------------- migrations.py | 3 +- models.py | 1 + static/js/index.js | 2 +- views_api.py | 2 +- 5 files changed, 287 insertions(+), 126 deletions(-) diff --git a/helpers/scan.py b/helpers/scan.py index 3aa1c5a..186ea17 100644 --- a/helpers/scan.py +++ b/helpers/scan.py @@ -5,11 +5,8 @@ belonging to the wallet's Silent Payment address. Oracle endpoints used: - GET /tweaks/{height}?dustLimit={dust} — per-block tweaks + GET /tweaks/{height} — per-block tweaks GET /utxos/{height} — per-block UTXOs - GET /filter/spent/{height} — spent outpoints filter (GCS) - -Mirrors the logic in blindbit-scan/pkg/daemon/scan.go. """ from __future__ import annotations @@ -33,6 +30,7 @@ update_balance, get_or_create_server_secret, get_silnt_wallet, + get_wallet_addresses ) from .wallet import decrypt_secret, decrypt_spend_key @@ -206,12 +204,12 @@ def create_label(scan_key: bytes, m: int) -> Label: return Label(pub_key=pub_key, tweak=tweak, m=m) -def create_labels(scan_key: bytes, count: int = 21) -> list[Label]: +def create_labels(scan_key: bytes, indices: list[int]) -> list[Label]: """ Create `count` labels starting from m=0 (change label). Mirrors BlindBit's labelCount config. - """ - return [create_label(scan_key, m) for m in range(count)] + """ + return [create_label(scan_key, m) for m in indices] # --------------------------------------------------------------------------- @@ -340,6 +338,95 @@ def receiver_scan_transaction( # --------------------------------------------------------------------------- +def sync_block_from_compute_index( + index: list[dict], + scan_key: bytes, + spend_pub_key: bytes, + labels: list[Label], +) -> list[OwnedUTXO]: + """ + Process Compute Index response. + Each entry has: {txid, tweak, outputs: [x-only-hex, ...]} + """ + owned_utxos: list[OwnedUTXO] = [] + + for entry in index: + tweak_hex = entry.get("tweak", "") + txid = entry.get("txid", "") + outputs_hex = entry.get("outputs", []) + + if not tweak_hex or not outputs_hex: + continue + + try: + tweak_bytes = bytes.fromhex(tweak_hex) + # outputs are shortened (8 bytes / 16 hex chars) — can only use for + # matching, not for full pubkey recovery. Use receiver_scan_transaction + # with the full tweak to derive expected outputs and match. + shared_secret = create_shared_secret(tweak_bytes, scan_key, input_hash=None) + + # Derive expected x-only outputs for k=0,1,2... + # outputs in compute index are shortened — 8 bytes each + # Build set for fast lookup + short_outputs = set(outputs_hex) + + # Check if any of our derived outputs match + k = 0 + while True: + output_pub_key, t_k = create_output_pub_key_and_tweak( + shared_secret, spend_pub_key, k + ) + short = output_pub_key.hex()[:16] # first 8 bytes + + matched = False + + # Direct match + if short in short_outputs: + owned_utxos.append(OwnedUTXO( + txid=bytes.fromhex(txid), + vout=k, # vout not available in compute index + amount=0, # amount not available — fetch separately if needed + priv_key_tweak=t_k, + pub_key=output_pub_key, + utxo_state="unspent", + timestamp=0, + label=None, + )) + matched = True + + # Label match + if labels: + out_pk_33 = b"\x02" + output_pub_key + for label in labels: + try: + label_out = add_public_keys(out_pk_33, label.pub_key) + label_short = label_out[1:].hex()[:16] + if label_short in short_outputs: + sec_key_tweak = add_private_keys(t_k, label.tweak) + owned_utxos.append(OwnedUTXO( + txid=bytes.fromhex(txid), + vout=k, + amount=0, + priv_key_tweak=sec_key_tweak, + pub_key=label_out[1:], + utxo_state="unspent", + timestamp=0, + label=label, + )) + matched = True + except Exception: + pass + + if not matched: + break + k += 1 + + except Exception as e: + logger.warning(f"compute_index entry error for txid {txid}: {e}") + continue + + return owned_utxos + def sync_block( tweaks: list[bytes | str], # list of 33-byte tweaks, bytes or hex strings utxos: list[ @@ -352,9 +439,9 @@ def sync_block( # Step 1 & 2: precompute potential output pubkeys for every tweak tweak_script_map: dict[bytes, tuple[bytes, bytes]] = {} - tweak = bytes.fromhex(tweaks[0]) if isinstance(tweaks[0], str) else tweaks[0] - shared = create_shared_secret(tweak, scan_key, None) - t_k, _ = create_output_pub_key_and_tweak(shared, spend_pub_key, 0) + # tweak = bytes.fromhex(tweaks[0]) if isinstance(tweaks[0], str) else tweaks[0] + # shared = create_shared_secret(tweak, scan_key, None) + # t_k, _ = create_output_pub_key_and_tweak(shared, spend_pub_key, 0) for raw_tweak in tweaks: tweak = bytes.fromhex(raw_tweak) if isinstance(raw_tweak, str) else raw_tweak shared_secret = create_shared_secret(tweak, scan_key, input_hash=None) @@ -385,7 +472,7 @@ def sync_block( for utxo in utxos: txid_b = bytes.fromhex(utxo["txid"]) - x_only = bytes.fromhex(utxo["scriptpubkey"])[2:] + x_only = bytes.fromhex(utxo["pubkey"]) txid_groups.setdefault(txid_b, []).append(utxo) helper_mapping[x_only] = txid_b @@ -399,7 +486,7 @@ def sync_block( owned_utxos: list[OwnedUTXO] = [] for tweak, relevant_utxos in tweaks_outputs_to_check.items(): - tx_outputs = [bytes.fromhex(u["scriptpubkey"])[2:] for u in relevant_utxos] + tx_outputs = [bytes.fromhex(u["pubkey"]) for u in relevant_utxos] found = receiver_scan_transaction( scan_key=scan_key, @@ -412,16 +499,16 @@ def sync_block( for fo in found: for utxo in relevant_utxos: - if fo.output == bytes.fromhex(utxo["scriptpubkey"])[2:]: + if fo.output == bytes.fromhex(utxo["pubkey"]): owned_utxos.append( OwnedUTXO( txid=bytes.fromhex(utxo["txid"]), vout=utxo["vout"], - amount=utxo["value"], + amount=utxo["amount"], priv_key_tweak=fo.sec_key_tweak, pub_key=fo.output, - utxo_state="spent" if utxo.get("spent") else "unspent", - timestamp=utxo.get("timestamp"), + utxo_state="unspent", + timestamp=utxo.get("timestamp", 0), label=fo.label, ) ) @@ -445,20 +532,20 @@ def _client(self) -> httpx.AsyncClient: async def get_chain_tip(self) -> int: async with self._client() as client: - resp = await client.get(f"{self.base_url}/block-height") + resp = await client.get(f"{self.base_url}/info") resp.raise_for_status() - return resp.json()["block_height"] + return resp.json()["height"] async def get_tweaks( - self, height: int, dust_limit: int = DUST_LIMIT + self, height: int ) -> list[bytes]: """Returns list of 33-byte compressed pubkey tweaks for the block.""" async with self._client() as client: resp = await client.get( - f"{self.base_url}/tweaks/{height}", params={"dustLimit": dust_limit} + f"{self.base_url}/tweaks/{height}" ) resp.raise_for_status() - data = resp.json() + data = resp.json()["index"] tweaks = [] for t in data: tweaks.append(bytes.fromhex(t)) @@ -469,20 +556,44 @@ async def get_utxos(self, height: int) -> list[dict]: async with self._client() as client: resp = await client.get(f"{self.base_url}/utxos/{height}") resp.raise_for_status() - return resp.json() - - async def get_spent_filter(self, height: int) -> Optional[dict]: - """Returns the spent outpoints GCS filter for the block.""" + return resp.json()["index"] + + # async def get_spent_filter(self, height: int) -> Optional[dict]: + # """Returns the spent outpoints GCS filter for the block.""" + # async with self._client() as client: + # resp = await client.get(f"{self.base_url}/filter/spent/{height}") + # if resp.status_code == 404: + # return None + # resp.raise_for_status() + # return resp.json() + + # async def get_spent_index(self, height: int) -> Optional[dict]: + # async with self._client() as client: + # resp = await client.get(f"{self.base_url}/spent-outputs/{height}") + # if resp.status_code == 404: + # return None + # resp.raise_for_status() + # return resp.json() + + async def get_spent_outputs(self, height: int) -> Optional[dict]: + """ + Spent Outputs (Shortened) — first 8 bytes of x-only pubkeys of spent outputs. + Replaces deprecated spent-index endpoint. + """ async with self._client() as client: - resp = await client.get(f"{self.base_url}/filter/spent/{height}") + resp = await client.get(f"{self.base_url}/spent-outputs/{height}") if resp.status_code == 404: return None resp.raise_for_status() return resp.json() - async def get_spent_index(self, height: int) -> Optional[dict]: + async def get_compute_index(self, height: int) -> Optional[dict]: + """ + Compute Index — combined tweak + output info per transaction. + Can replace separate tweaks + utxos calls. + """ async with self._client() as client: - resp = await client.get(f"{self.base_url}/spent-index/{height}") + resp = await client.get(f"{self.base_url}/compute-index/{height}") if resp.status_code == 404: return None resp.raise_for_status() @@ -491,7 +602,7 @@ async def get_spent_index(self, height: int) -> Optional[dict]: async def get_block_hash(self, height: int) -> Optional[dict]: """Returns the hash for the block.""" async with self._client() as client: - resp = await client.get(f"{self.base_url}/block-hash/{height}") + resp = await client.get(f"{self.base_url}/blockhash/{height}") if resp.status_code == 404: return None resp.raise_for_status() @@ -507,85 +618,100 @@ async def scan_block( scan_secret_bytes: bytes, spend_pub_bytes: bytes, spend_secret_bytes: bytes, -) -> list[dict]: - """ - Scan a single block for UTXOs belonging to this wallet. - Returns list of owned UTXO dicts ready for DB insertion. - """ - tweaks = await client.get_tweaks(height, DUST_LIMIT) - labels: list[Label] = [] + labels: list[Label], # ← pre-computed, passed in +) -> list[OwnedUTXO]: + """Scan a single block. Labels are pre-computed outside the loop.""" + + # Try Compute Index first + compute_data = await client.get_compute_index(height) + if compute_data: + matches = sync_block_from_compute_index( + compute_data["index"], + scan_secret_bytes, + spend_pub_bytes, + labels + ) + if matches: + # Only fetch full utxos if we have matches + full_utxos = await client.get_utxos(height) + utxo_lookup = {u["pubkey"]: u for u in full_utxos if "pubkey" in u} + for owned in matches: + pub_hex = owned.pub_key.hex() + full = utxo_lookup.get(pub_hex) + if not full: + # fallback: match by short prefix + short = pub_hex[:16] + full = next( + (u for u in full_utxos if u.get("pubkey", "")[:16] == short), + None + ) + if full: + owned.vout = full.get("vout", owned.vout) + owned.amount = full.get("amount", owned.amount) + owned.timestamp = full.get("timestamp", owned.timestamp) + owned.utxo_state = "spent" if full.get("spent") else "unspent" + owned.pub_key = bytes.fromhex(full["pubkey"]) + return matches + + # Fallback: separate tweaks + utxos + tweaks = await client.get_tweaks(height) + if not tweaks: + return [] utxos = await client.get_utxos(height) if not utxos: - return [] - labels = create_labels(scan_secret_bytes, count=21) - owned = sync_block(tweaks, utxos, scan_secret_bytes, spend_pub_bytes, labels) - - return owned + return [] + return sync_block(tweaks, utxos, scan_secret_bytes, spend_pub_bytes, labels) -async def mark_spent_utxos( - height: int, +async def mark_spent_utxos_batch( + heights: list[int], client: BlindBitOracleClient, wallet_id: str, + owned_utxos_lookup: dict[str, dict], # txid:vout -> row — pre-fetched ) -> None: """ - Check spent outpoints index and mark UTXOs as spent in the DB. - Skips GCS filter check — fetches spent index directly for owned UTXOs. + Check spent outputs for a batch of heights. + owned_utxos_lookup is pre-fetched once per scan batch. """ - try: - # Get current unconfirmd_spent and unspent UTXOs from DB - rows = await db.fetchall( - "SELECT txid, vout FROM silnt.utxos WHERE wallet_id = :wallet_id AND utxo_state in ('unspent','unconfirmed_spent')", - {"wallet_id": wallet_id}, - ) - if not rows: - return - - # Fetch block hash for this height - block_hash_data = await client.get_block_hash(height) - if not block_hash_data: - return - block_hash_bytes = bytes.fromhex(block_hash_data.get("block_hash")) - block_hash_le = block_hash_bytes[::-1] - - # Compute short hashes for our UTXOs - our_hashes: dict[str, dict] = {} - for row in rows: - txid_le = bytes.fromhex(row["txid"])[::-1] - vout_bytes = struct.pack(" Date: Sat, 2 May 2026 08:52:08 +0100 Subject: [PATCH 48/83] fix utxo date; set oracle fork --- README.md | 6 ++-- helpers/scan.py | 41 ++++++++++------------- static/components/utxo-list.js | 18 ++++++++-- templates/silnt/components/utxo-list.html | 7 ++-- 4 files changed, 39 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 3136ead..c36f799 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SiLNt — Silent Payments Wallet Extension for LNbits -A [LNbits](https://lnbits.com) extension for managing [Silent Payment](https://silentpayments.xyz) Bitcoin wallets, with blockchain scanning powered by a self-hosted [BlindBit Oracle](https://github.com/setavenger/blindbit-oracle). +A [LNbits](https://lnbits.com) extension for managing [Silent Payment](https://silentpayments.xyz) Bitcoin wallets, with blockchain scanning powered by a self-hosted [BlindBit Oracle](https://github.com/ponthief/blindbit-oracle). --- @@ -23,7 +23,7 @@ A [LNbits](https://lnbits.com) extension for managing [Silent Payment](https://s - LNbits instance (self-hosted) - Python dependencies: `embit`, `httpx`, `coincurve`, `cryptography`, `dnspython`, `ecdsa` -- A running [blindbit-oracle](https://github.com/setavenger/blindbit-oracle) instance for blockchain scanning +- A running [blindbit-oracle](https://github.com/ponthief/blindbit-oracle) instance for blockchain scanning --- @@ -284,7 +284,7 @@ siLNt/ - [BIP352 — Silent Payments](https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki) - [BIP353 — DNS Payment Instructions](https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki) - [BIP352 Light Client Specification](https://github.com/setavenger/BIP0352-light-client-specification) -- [BlindBit Oracle](https://github.com/setavenger/blindbit-oracle) +- [BlindBit Oracle](https://github.com/ponthief/blindbit-oracle) --- diff --git a/helpers/scan.py b/helpers/scan.py index 186ea17..aa1931f 100644 --- a/helpers/scan.py +++ b/helpers/scan.py @@ -556,24 +556,7 @@ async def get_utxos(self, height: int) -> list[dict]: async with self._client() as client: resp = await client.get(f"{self.base_url}/utxos/{height}") resp.raise_for_status() - return resp.json()["index"] - - # async def get_spent_filter(self, height: int) -> Optional[dict]: - # """Returns the spent outpoints GCS filter for the block.""" - # async with self._client() as client: - # resp = await client.get(f"{self.base_url}/filter/spent/{height}") - # if resp.status_code == 404: - # return None - # resp.raise_for_status() - # return resp.json() - - # async def get_spent_index(self, height: int) -> Optional[dict]: - # async with self._client() as client: - # resp = await client.get(f"{self.base_url}/spent-outputs/{height}") - # if resp.status_code == 404: - # return None - # resp.raise_for_status() - # return resp.json() + return resp.json()["index"] async def get_spent_outputs(self, height: int) -> Optional[dict]: """ @@ -645,12 +628,12 @@ async def scan_block( (u for u in full_utxos if u.get("pubkey", "")[:16] == short), None ) - if full: + if full: owned.vout = full.get("vout", owned.vout) owned.amount = full.get("amount", owned.amount) - owned.timestamp = full.get("timestamp", owned.timestamp) - owned.utxo_state = "spent" if full.get("spent") else "unspent" - owned.pub_key = bytes.fromhex(full["pubkey"]) + owned.timestamp = await get_block_ts(full.get("txid")) + owned.utxo_state = "unspent" + owned.pub_key = bytes.fromhex(full["pubkey"]) return matches # Fallback: separate tweaks + utxos @@ -800,7 +783,7 @@ async def scan_wallet( set_scan_progress(wallet_id, 0, total_blocks, 0) # ── Batch size for concurrent scanning ──────────────────────────────────── - BATCH_SIZE = 10 + BATCH_SIZE = 30 heights = list(range(start, end + 1)) @@ -919,3 +902,15 @@ def set_scan_progress( "total": total, "found": found, } + +async def get_block_ts(txid) -> int: + blindbit = await get_blindbit_config() + mempool_base = (blindbit.mempool_url or "https://mempool.space").rstrip("/") + async with httpx.AsyncClient(timeout=10.0) as client: + resp = await client.get(f"{mempool_base}/api/tx/{txid}") + if resp.status_code == 200: + tx_data = resp.json() + ts = tx_data.get("status", {}).get("block_time") or 0 + if ts: + return int(ts) + return 0 \ No newline at end of file diff --git a/static/components/utxo-list.js b/static/components/utxo-list.js index 02dd227..92c4a9b 100644 --- a/static/components/utxo-list.js +++ b/static/components/utxo-list.js @@ -114,6 +114,21 @@ window.app.component('utxo-list', { .filter(u => u.utxo_state === 'spent') .reduce((t, u) => t + (u.amount || 0), 0) }, + formatTimestamp: function (timestamp) { + if (!timestamp) return 'N/A' + try { + const date = new Date(timestamp * 1000) + const day = String(date.getDate()).padStart(2, '0') + const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] + const month = months[date.getMonth()] + const year = date.getFullYear() + const hours = String(date.getHours()).padStart(2, '0') + const mins = String(date.getMinutes()).padStart(2, '0') + return `${day} ${month} ${year} ${hours}:${mins}` + } catch (e) { + return 'Unknown' + } + }, updateUtxoSelection: function () { this.utxoSelectAmount = this.payedAmount this.applyUtxoSelectionMode() @@ -149,7 +164,6 @@ window.app.component('utxo-list', { return total }, 0) } - }, - + }, created: async function () {} }) \ No newline at end of file diff --git a/templates/silnt/components/utxo-list.html b/templates/silnt/components/utxo-list.html index 072a019..eae3b43 100644 --- a/templates/silnt/components/utxo-list.html +++ b/templates/silnt/components/utxo-list.html @@ -117,12 +117,9 @@ -
-
+
+
N/A
- From 5ede7d081a04bc02a6be27d81e7ba507d9c77dad Mon Sep 17 00:00:00 2001 From: Ponthief Date: Sun, 3 May 2026 09:27:00 +0100 Subject: [PATCH 49/83] fixes to lable generation utxo discovery --- crud.py | 12 +- helpers/scan.py | 925 ++++++++++++---------------------------------- helpers/wallet.py | 30 +- 3 files changed, 256 insertions(+), 711 deletions(-) diff --git a/crud.py b/crud.py index 384d2c2..7103ee7 100644 --- a/crud.py +++ b/crud.py @@ -164,12 +164,16 @@ async def insert_utxos_for_wallet(wallet_id: str, utxos: list) -> None: await db.execute( """INSERT INTO silnt.utxos (txid, vout, amount, priv_key_tweak, pub_key, utxo_state, timestamp, wallet_id) VALUES (:txid, :vout, :amount, :priv_key_tweak, :pub_key, :utxo_state, :timestamp, :wallet_id) - ON CONFLICT (txid, vout) DO UPDATE SET - utxo_state = EXCLUDED.utxo_state, + ON CONFLICT (txid) DO UPDATE SET amount = EXCLUDED.amount, priv_key_tweak = EXCLUDED.priv_key_tweak, - pub_key = EXCLUDED.pub_key""", - utxo.to_db_row(wallet_id), + pub_key = EXCLUDED.pub_key, + utxo_state = CASE + WHEN silnt.utxos.utxo_state IN ('spent', 'unconfirmed_spent') + THEN silnt.utxos.utxo_state + ELSE EXCLUDED.utxo_state + END""", + utxo.to_db_row(wallet_id) ) async def update_unconfirmed_utxo(wallet_id: str, txid: str): diff --git a/helpers/scan.py b/helpers/scan.py index aa1931f..4fcbe86 100644 --- a/helpers/scan.py +++ b/helpers/scan.py @@ -1,661 +1,311 @@ """ scan.py — Silent Payments blockchain scanner for the silnt LNbits extension. - -Connects to a BlindBit Oracle (https://localhost:8001) and scans for UTXOs -belonging to the wallet's Silent Payment address. - -Oracle endpoints used: - GET /tweaks/{height} — per-block tweaks - GET /utxos/{height} — per-block UTXOs """ - from __future__ import annotations -import asyncio -import coincurve -import hashlib -import json -import ssl -import struct -from binascii import hexlify, unhexlify +import asyncio, hashlib, struct +from dataclasses import dataclass from typing import Optional - -import httpx +import coincurve, httpx +from coincurve import PublicKey from loguru import logger - -from ..crud import ( - db, - get_silnt_wallets, - get_blindbit_config, - insert_utxos_for_wallet, - update_balance, - get_or_create_server_secret, - get_silnt_wallet, - get_wallet_addresses -) +from ..crud import db, get_blindbit_config, get_silnt_wallet, get_silnt_wallets, get_wallet_addresses, insert_utxos_for_wallet, update_balance from .wallet import decrypt_secret, decrypt_spend_key -import hashlib -import struct -from dataclasses import dataclass, field -from typing import Optional - -from coincurve import PublicKey, PrivateKey - -# In-memory progress store — keyed by wallet_id _scan_progress: dict[str, dict] = {} - _scan_stop: dict[str, bool] = {} - -# ── Constants ────────────────────────────────────────────────────────────────── SECP256K1_N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 -DUST_LIMIT = 100 - -# --------------------------------------------------------------------------- -# Types -# --------------------------------------------------------------------------- @dataclass class Label: - pub_key: bytes # 33-byte compressed pubkey - tweak: bytes # 32-byte scalar + pub_key: bytes + tweak: bytes address: str = "" m: int = 0 - @dataclass class FoundOutput: - output: bytes # 32-byte x-only pubkey - sec_key_tweak: bytes # 32-byte scalar + output: bytes + sec_key_tweak: bytes label: Optional[Label] = None - -@dataclass -class UTXOServed: - txid: bytes # 32 bytes (little-endian as stored) - vout: int - amount: int # sats - script_pubkey: bytes # full scriptpubkey (34 bytes for P2TR: OP_1 OP_PUSH32 <32>) - spent: bool = False - timestamp: int = 0 - - @dataclass class OwnedUTXO: txid: bytes vout: int amount: int priv_key_tweak: bytes - pub_key: bytes # 32-byte x-only - utxo_state: str # "unspent" | "spent" | "unconfirmed_spent" + pub_key: bytes + utxo_state: str timestamp: int = 0 label: Optional[Label] = None def to_db_row(self, wallet_id: str) -> dict: - """Returns dict ready for DB insert.""" - return { - "txid": self.txid.hex(), - "vout": self.vout, - "amount": self.amount, - "priv_key_tweak": self.priv_key_tweak.hex(), - "pub_key": self.pub_key.hex(), - "utxo_state": self.utxo_state, - "timestamp": self.timestamp, - "wallet_id": wallet_id, - } - - -def request_scan_stop(wallet_id: str): - _scan_stop[wallet_id] = True - - -def should_stop(wallet_id: str) -> bool: - return _scan_stop.get(wallet_id, False) + return {"txid": self.txid.hex(), "vout": self.vout, "amount": self.amount, + "priv_key_tweak": self.priv_key_tweak.hex(), "pub_key": self.pub_key.hex(), + "utxo_state": self.utxo_state, "timestamp": self.timestamp, "wallet_id": wallet_id} -def clear_scan_stop(wallet_id: str): - _scan_stop.pop(wallet_id, None) - - -# --------------------------------------------------------------------------- -# Elliptic curve helpers (secp256k1 via coincurve) -# --------------------------------------------------------------------------- +def request_scan_stop(wallet_id: str): _scan_stop[wallet_id] = True +def should_stop(wallet_id: str) -> bool: return _scan_stop.get(wallet_id, False) +def clear_scan_stop(wallet_id: str): _scan_stop.pop(wallet_id, None) def _tagged_hash(tag: str, data: bytes) -> bytes: - tag_hash = hashlib.sha256(tag.encode()).digest() - return hashlib.sha256(tag_hash + tag_hash + data).digest() - + h = hashlib.sha256(tag.encode()).digest() + return hashlib.sha256(h + h + data).digest() def _ser_u32(k: int) -> bytes: - """Serialize uint32 as big-endian 4 bytes, matching Go's binary.BigEndian.""" return struct.pack(">I", k) - -def create_shared_secret( - public_component: bytes, # 33-byte compressed pubkey (tweak or A_sum) - scan_key: bytes, # 32-byte secret scalar - input_hash: Optional[bytes] = None, -) -> bytes: - """ - shared_secret = scan_key * public_component (optionally * input_hash first) - Mirrors Go: btcec.S256().ScalarMult(pubKey.X(), pubKey.Y(), secretComponent[:]) - """ +def create_shared_secret(public_component: bytes, scan_key: bytes, input_hash: Optional[bytes] = None) -> bytes: if input_hash is not None: - # secretComponent = MultPrivateKeys(scan_key, input_hash) - n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - scalar = ( - int.from_bytes(scan_key, "big") * int.from_bytes(input_hash, "big") - ) % n + scalar = (int.from_bytes(scan_key, "big") * int.from_bytes(input_hash, "big")) % SECP256K1_N effective_key = scalar.to_bytes(32, "big") else: effective_key = scan_key return PublicKey(public_component).multiply(effective_key).format(compressed=True) - -def create_output_pub_key_and_tweak( - shared_secret: bytes, # 33-byte compressed - spend_pub_key: bytes, # 33-byte compressed - k: int, -) -> tuple[bytes, bytes]: - """ - t_k = TaggedHash("BIP0352/SharedSecret", shared_secret || ser_u32(k)) - P_k = B_spend + t_k*G (x-only returned) - """ +def create_output_pub_key_and_tweak(shared_secret: bytes, spend_pub_key: bytes, k: int) -> tuple[bytes, bytes]: t_k = _tagged_hash("BIP0352/SharedSecret", shared_secret + _ser_u32(k)) - # t_k * G - tk_point = PublicKey.from_secret(t_k) - # P_k = B_spend + t_k*G - p_k = PublicKey(spend_pub_key).combine([tk_point]).format(compressed=True) - return p_k[1:], t_k # (32-byte x-only, 32-byte tweak) - + p_k = PublicKey(spend_pub_key).combine([PublicKey.from_secret(t_k)]).format(compressed=True) + return p_k[1:], t_k def add_public_keys(pk1: bytes, pk2: bytes) -> bytes: - """Add two 33-byte compressed pubkeys. Returns 33-byte result.""" - if isinstance(pk1, PublicKey): - pk1 = pk1.format(compressed=True) - if isinstance(pk2, PublicKey): - pk2 = pk2.format(compressed=True) + if isinstance(pk1, PublicKey): pk1 = pk1.format(compressed=True) + if isinstance(pk2, PublicKey): pk2 = pk2.format(compressed=True) return PublicKey(pk1).combine([PublicKey(pk2)]).format(compressed=True) - def negate_public_key(pk: bytes) -> bytes: - """Return the negated 33-byte compressed pubkey.""" - # Flip parity byte 0x02 <-> 0x03 - parity = 0x02 if pk[0] == 0x03 else 0x03 - return bytes([parity]) + pk[1:] - + return bytes([0x02 if pk[0] == 0x03 else 0x03]) + pk[1:] def add_private_keys(sk1: bytes, sk2: bytes) -> bytes: - """Add two 32-byte scalars mod n. Returns 32-byte result.""" - n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - result = (int.from_bytes(sk1, "big") + int.from_bytes(sk2, "big")) % n - return result.to_bytes(32, "big") - + return ((int.from_bytes(sk1, "big") + int.from_bytes(sk2, "big")) % SECP256K1_N).to_bytes(32, "big") def create_label(scan_key: bytes, m: int) -> Label: - """ - label_tweak = TaggedHash("BIP0352/Label", scan_key || ser_u32(m)) - label_pub = label_tweak * G - Mirrors Go: bip352.CreateLabel(scanSecKey, m) - """ tweak = _tagged_hash("BIP0352/Label", scan_key + _ser_u32(m)) - pub_key = PublicKey.from_secret(tweak).format(compressed=True) - return Label(pub_key=pub_key, tweak=tweak, m=m) - + # """Old broken derivation — little-endian ser32, for recovery only.""" + # tag = b"BIP0352/Label" + # tag_hash = hashlib.sha256(tag).digest() + # tweak = hashlib.sha256( + # tag_hash + tag_hash + scan_key + m.to_bytes(4, 'little') + # ).digest() + return Label(pub_key=PublicKey.from_secret(tweak).format(compressed=True), tweak=tweak, m=m) def create_labels(scan_key: bytes, indices: list[int]) -> list[Label]: - """ - Create `count` labels starting from m=0 (change label). - Mirrors BlindBit's labelCount config. - """ - return [create_label(scan_key, m) for m in indices] - - -# --------------------------------------------------------------------------- -# Label matching -# --------------------------------------------------------------------------- - - -def match_labels( - tx_output_33: bytes, # 33-byte compressed - pk_33: bytes, # 33-byte derived output pubkey - labels: list[Label], -) -> Optional[Label]: - """ - Computes tx_output - pk (i.e. tx_output + (-pk)) and checks against labels. - """ - pk_neg = negate_public_key(pk_33) + return [create_label(scan_key, m) for m in sorted(set([0] + indices))] + +def match_labels(tx_output_33: bytes, pk_33: bytes, labels: list[Label]) -> Optional[Label]: try: - diff = add_public_keys(tx_output_33, pk_neg) + diff = add_public_keys(tx_output_33, negate_public_key(pk_33)) except Exception: return None - for label in labels: if diff[1:] == label.pub_key[1:]: return label return None - -# --------------------------------------------------------------------------- -# Core scanning: mirrors ReceiverScanTransactionWithSharedSecret -# --------------------------------------------------------------------------- - - def receiver_scan_transaction_with_shared_secret( - scan_key: bytes, # 32-byte - spend_pub_key: bytes, # 33-byte compressed - labels: list[Label], - tx_outputs: list[bytes], # list of 32-byte x-only pubkeys - shared_secret: bytes, # 33-byte compressed + scan_key: bytes, spend_pub_key: bytes, labels: list[Label], + tx_outputs: list[bytes], shared_secret: bytes, ) -> list[FoundOutput]: found_outputs: list[FoundOutput] = [] - remaining = list(tx_outputs) # copy so we can remove matched outputs + remaining = list(tx_outputs) k = 0 - while True: - output_pub_key, tweak = create_output_pub_key_and_tweak( - shared_secret, spend_pub_key, k - ) + output_pub_key, tweak = create_output_pub_key_and_tweak(shared_secret, spend_pub_key, k) found = False for i, tx_output in enumerate(remaining): - # --- Direct match --- if output_pub_key == tx_output: - found_outputs.append( - FoundOutput( - output=tx_output, - sec_key_tweak=tweak, - label=None, - ) - ) - remaining.pop(i) - found = True - k += 1 - break - + found_outputs.append(FoundOutput(output=tx_output, sec_key_tweak=tweak)) + remaining.pop(i); found = True; k += 1; break if not labels: continue - - # --- Label matching --- tx_out_33 = b"\x02" + tx_output out_pk_33 = b"\x02" + output_pub_key - - # Try normal output against labels - found_label = match_labels(tx_out_33, out_pk_33, labels) - if found_label is not None: - sec_key_tweak = add_private_keys(tweak, found_label.tweak) - found_outputs.append( - FoundOutput( - output=tx_output, - sec_key_tweak=sec_key_tweak, - label=found_label, - ) - ) - remaining.pop(i) - found = True - k += 1 - break - - # Try negated tx_output against labels - tx_out_33_neg = negate_public_key(tx_out_33) - found_label = match_labels(tx_out_33_neg, out_pk_33, labels) - if found_label is not None: - sec_key_tweak = add_private_keys(tweak, found_label.tweak) - found_outputs.append( - FoundOutput( - output=tx_out_33_neg[1:], # x-only of negated point - sec_key_tweak=sec_key_tweak, - label=found_label, - ) - ) - remaining.pop(i) - found = True - k += 1 - break - + fl = match_labels(tx_out_33, out_pk_33, labels) + if fl: + found_outputs.append(FoundOutput(output=tx_output, sec_key_tweak=add_private_keys(tweak, fl.tweak), label=fl)) + remaining.pop(i); found = True; k += 1; break + tx_out_neg = negate_public_key(tx_out_33) + fl = match_labels(tx_out_neg, out_pk_33, labels) + if fl: + found_outputs.append(FoundOutput(output=tx_out_neg[1:], sec_key_tweak=add_private_keys(tweak, fl.tweak), label=fl)) + remaining.pop(i); found = True; k += 1; break if not found: break - return found_outputs - -def receiver_scan_transaction( - scan_key: bytes, - spend_pub_key: bytes, - labels: list[Label], - tx_outputs: list[bytes], - public_component: bytes, # 33-byte tweak or A_sum - input_hash: Optional[bytes], # None if public_component already includes it -) -> list[FoundOutput]: - shared_secret = create_shared_secret(public_component, scan_key, input_hash) +def receiver_scan_transaction(scan_key, spend_pub_key, labels, tx_outputs, public_component, input_hash): return receiver_scan_transaction_with_shared_secret( - scan_key, spend_pub_key, labels, tx_outputs, shared_secret - ) + scan_key, spend_pub_key, labels, tx_outputs, + create_shared_secret(public_component, scan_key, input_hash)) +def sync_block(tweaks, utxos, scan_key, spend_pub_key, labels): + tweak_script_map: dict[bytes, tuple[bytes, bytes]] = {} + raw = tweaks[0] + tweak = bytes.fromhex(raw) if isinstance(raw, str) else raw + ss = create_shared_secret(tweak, scan_key) + opk, _ = create_output_pub_key_and_tweak(ss, spend_pub_key, 0) + for raw in tweaks: + tweak = bytes.fromhex(raw) if isinstance(raw, str) else raw + ss = create_shared_secret(tweak, scan_key) + opk, _ = create_output_pub_key_and_tweak(ss, spend_pub_key, 0) + tweak_script_map[opk] = (tweak, opk) + b33 = b"\x02" + opk + for label in labels: + try: + lo = add_public_keys(b33, label.pub_key) + tweak_script_map[lo[1:]] = (tweak, lo[1:]) + except Exception as e: + logger.debug(f"label add m={label.m}: {e}") + try: + lon = add_public_keys(b33, negate_public_key(label.pub_key)) + tweak_script_map[lon[1:]] = (tweak, lon[1:]) + except Exception as e: + logger.debug(f"label neg m={label.m}: {e}") + if not tweak_script_map: + return [] + txid_groups: dict[bytes, list[dict]] = {} + helper_mapping: dict[bytes, bytes] = {} + for u in utxos: + tb = bytes.fromhex(u["txid"]) + xo = bytes.fromhex(u["pubkey"]) + txid_groups.setdefault(tb, []).append(u) + helper_mapping[xo] = tb + to_check: dict[bytes, list[dict]] = {} + for xo, (tw, _) in tweak_script_map.items(): + if xo in helper_mapping: + to_check[tw] = txid_groups[helper_mapping[xo]] + owned: list[OwnedUTXO] = [] + for tw, rel_utxos in to_check.items(): + found = receiver_scan_transaction(scan_key, spend_pub_key, labels, + [bytes.fromhex(u["pubkey"]) for u in rel_utxos], tw, None) + for fo in found: + for u in rel_utxos: + if fo.output == bytes.fromhex(u["pubkey"]): + owned.append(OwnedUTXO(txid=bytes.fromhex(u["txid"]), vout=u["vout"], + amount=u["amount"], priv_key_tweak=fo.sec_key_tweak, pub_key=fo.output, + utxo_state="unspent", timestamp=u.get("timestamp", 0), label=fo.label)) + break + return owned -# --------------------------------------------------------------------------- -# Block-level scan: mirrors syncBlock -# --------------------------------------------------------------------------- - - -def sync_block_from_compute_index( - index: list[dict], - scan_key: bytes, - spend_pub_key: bytes, - labels: list[Label], -) -> list[OwnedUTXO]: - """ - Process Compute Index response. - Each entry has: {txid, tweak, outputs: [x-only-hex, ...]} - """ - owned_utxos: list[OwnedUTXO] = [] - +def sync_block_from_compute_index(index, scan_key, spend_pub_key, labels): + owned: list[OwnedUTXO] = [] for entry in index: tweak_hex = entry.get("tweak", "") txid = entry.get("txid", "") outputs_hex = entry.get("outputs", []) - if not tweak_hex or not outputs_hex: continue - try: - tweak_bytes = bytes.fromhex(tweak_hex) - # outputs are shortened (8 bytes / 16 hex chars) — can only use for - # matching, not for full pubkey recovery. Use receiver_scan_transaction - # with the full tweak to derive expected outputs and match. - shared_secret = create_shared_secret(tweak_bytes, scan_key, input_hash=None) - - # Derive expected x-only outputs for k=0,1,2... - # outputs in compute index are shortened — 8 bytes each - # Build set for fast lookup - short_outputs = set(outputs_hex) - - # Check if any of our derived outputs match + ss = create_shared_secret(bytes.fromhex(tweak_hex), scan_key) + shorts = set(outputs_hex) k = 0 while True: - output_pub_key, t_k = create_output_pub_key_and_tweak( - shared_secret, spend_pub_key, k - ) - short = output_pub_key.hex()[:16] # first 8 bytes - + opk, t_k = create_output_pub_key_and_tweak(ss, spend_pub_key, k) matched = False - - # Direct match - if short in short_outputs: - owned_utxos.append(OwnedUTXO( - txid=bytes.fromhex(txid), - vout=k, # vout not available in compute index - amount=0, # amount not available — fetch separately if needed - priv_key_tweak=t_k, - pub_key=output_pub_key, - utxo_state="unspent", - timestamp=0, - label=None, - )) + if opk.hex()[:16] in shorts: + owned.append(OwnedUTXO(txid=bytes.fromhex(txid), vout=0, amount=0, + priv_key_tweak=t_k, pub_key=opk, utxo_state="unspent")) matched = True - - # Label match if labels: - out_pk_33 = b"\x02" + output_pub_key + b33 = b"\x02" + opk for label in labels: try: - label_out = add_public_keys(out_pk_33, label.pub_key) - label_short = label_out[1:].hex()[:16] - if label_short in short_outputs: - sec_key_tweak = add_private_keys(t_k, label.tweak) - owned_utxos.append(OwnedUTXO( - txid=bytes.fromhex(txid), - vout=k, - amount=0, - priv_key_tweak=sec_key_tweak, - pub_key=label_out[1:], - utxo_state="unspent", - timestamp=0, - label=label, - )) + lo = add_public_keys(b33, label.pub_key) + if lo[1:].hex()[:16] in shorts: + owned.append(OwnedUTXO(txid=bytes.fromhex(txid), vout=0, amount=0, + priv_key_tweak=add_private_keys(t_k, label.tweak), + pub_key=lo[1:], utxo_state="unspent", label=label)) matched = True except Exception: pass - if not matched: break k += 1 - except Exception as e: - logger.warning(f"compute_index entry error for txid {txid}: {e}") - continue - - return owned_utxos - -def sync_block( - tweaks: list[bytes | str], # list of 33-byte tweaks, bytes or hex strings - utxos: list[ - dict - ], # raw dicts: {txid, vout, value, scriptpubkey, timestamp, spent, ...} - scan_key: bytes, # 32-byte secret scan key - spend_pub_key: bytes, # 33-byte compressed spend pubkey - labels: list[Label], -) -> list[OwnedUTXO]: - # Step 1 & 2: precompute potential output pubkeys for every tweak - tweak_script_map: dict[bytes, tuple[bytes, bytes]] = {} - - # tweak = bytes.fromhex(tweaks[0]) if isinstance(tweaks[0], str) else tweaks[0] - # shared = create_shared_secret(tweak, scan_key, None) - # t_k, _ = create_output_pub_key_and_tweak(shared, spend_pub_key, 0) - for raw_tweak in tweaks: - tweak = bytes.fromhex(raw_tweak) if isinstance(raw_tweak, str) else raw_tweak - shared_secret = create_shared_secret(tweak, scan_key, input_hash=None) - output_pub_key, _ = create_output_pub_key_and_tweak( - shared_secret, spend_pub_key, 0 - ) - tweak_script_map[output_pub_key] = (tweak, output_pub_key) - - out_pk_33 = b"\x02" + output_pub_key - for label in labels: - try: - label_out_33 = add_public_keys(out_pk_33, label.pub_key) - tweak_script_map[label_out_33[1:]] = (tweak, label_out_33[1:]) - except Exception: - pass - try: - neg_label_pub = negate_public_key(label.pub_key) - label_out_neg_33 = add_public_keys(out_pk_33, neg_label_pub) - tweak_script_map[label_out_neg_33[1:]] = (tweak, label_out_neg_33[1:]) - except Exception: - pass - if not tweak_script_map: - return [] - - # Step 3: group UTXOs by txid, build helper map: x-only -> txid bytes - txid_groups: dict[bytes, list[dict]] = {} - helper_mapping: dict[bytes, bytes] = {} - - for utxo in utxos: - txid_b = bytes.fromhex(utxo["txid"]) - x_only = bytes.fromhex(utxo["pubkey"]) - txid_groups.setdefault(txid_b, []).append(utxo) - helper_mapping[x_only] = txid_b - - # Step 4: collect tx groups that contain a precomputed candidate output - tweaks_outputs_to_check: dict[bytes, list[dict]] = {} - - for x_only, (tweak, _) in tweak_script_map.items(): - if x_only in helper_mapping: - tweaks_outputs_to_check[tweak] = txid_groups[helper_mapping[x_only]] - - owned_utxos: list[OwnedUTXO] = [] - - for tweak, relevant_utxos in tweaks_outputs_to_check.items(): - tx_outputs = [bytes.fromhex(u["pubkey"]) for u in relevant_utxos] - - found = receiver_scan_transaction( - scan_key=scan_key, - spend_pub_key=spend_pub_key, - labels=labels, - tx_outputs=tx_outputs, - public_component=tweak, - input_hash=None, - ) - - for fo in found: - for utxo in relevant_utxos: - if fo.output == bytes.fromhex(utxo["pubkey"]): - owned_utxos.append( - OwnedUTXO( - txid=bytes.fromhex(utxo["txid"]), - vout=utxo["vout"], - amount=utxo["amount"], - priv_key_tweak=fo.sec_key_tweak, - pub_key=fo.output, - utxo_state="unspent", - timestamp=utxo.get("timestamp", 0), - label=fo.label, - ) - ) - break - - return owned_utxos - - -# ── BlindBit Oracle client ───────────────────────────────────────────────────── + logger.warning(f"compute_index txid={txid}: {e}") + return owned class BlindBitOracleClient: - """HTTP client for the BlindBit Oracle.""" - - def __init__(self, base_url: str, user: str = "", password: str = ""): + def __init__(self, base_url: str): self.base_url = base_url.rstrip("/") - def _client(self) -> httpx.AsyncClient: - kwargs = {"timeout": 30.0, "verify": False} - return httpx.AsyncClient(**kwargs) + def _client(self): + return httpx.AsyncClient(timeout=30.0, verify=False) async def get_chain_tip(self) -> int: - async with self._client() as client: - resp = await client.get(f"{self.base_url}/info") - resp.raise_for_status() - return resp.json()["height"] - - async def get_tweaks( - self, height: int - ) -> list[bytes]: - """Returns list of 33-byte compressed pubkey tweaks for the block.""" - async with self._client() as client: - resp = await client.get( - f"{self.base_url}/tweaks/{height}" - ) - resp.raise_for_status() - data = resp.json()["index"] - tweaks = [] - for t in data: - tweaks.append(bytes.fromhex(t)) - return tweaks + async with self._client() as c: + return (await c.get(f"{self.base_url}/info")).json()["height"] + + async def get_tweaks(self, height: int) -> list[bytes]: + async with self._client() as c: + r = await c.get(f"{self.base_url}/tweaks/{height}") + r.raise_for_status() + d = r.json() + return [bytes.fromhex(t) for t in (d["index"] if isinstance(d, dict) else d)] async def get_utxos(self, height: int) -> list[dict]: - """Returns list of UTXOs served at this block height.""" - async with self._client() as client: - resp = await client.get(f"{self.base_url}/utxos/{height}") - resp.raise_for_status() - return resp.json()["index"] + async with self._client() as c: + r = await c.get(f"{self.base_url}/utxos/{height}") + r.raise_for_status() + d = r.json() + return d["index"] if isinstance(d, dict) else d async def get_spent_outputs(self, height: int) -> Optional[dict]: - """ - Spent Outputs (Shortened) — first 8 bytes of x-only pubkeys of spent outputs. - Replaces deprecated spent-index endpoint. - """ - async with self._client() as client: - resp = await client.get(f"{self.base_url}/spent-outputs/{height}") - if resp.status_code == 404: - return None - resp.raise_for_status() - return resp.json() + async with self._client() as c: + r = await c.get(f"{self.base_url}/spent-outputs/{height}") + return None if r.status_code == 404 else r.json() async def get_compute_index(self, height: int) -> Optional[dict]: - """ - Compute Index — combined tweak + output info per transaction. - Can replace separate tweaks + utxos calls. - """ - async with self._client() as client: - resp = await client.get(f"{self.base_url}/compute-index/{height}") - if resp.status_code == 404: - return None - resp.raise_for_status() - return resp.json() + async with self._client() as c: + r = await c.get(f"{self.base_url}/compute-index/{height}") + if r.status_code == 404: return None + d = r.json() + return d if isinstance(d, dict) and "index" in d else {"index": d} async def get_block_hash(self, height: int) -> Optional[dict]: - """Returns the hash for the block.""" - async with self._client() as client: - resp = await client.get(f"{self.base_url}/blockhash/{height}") - if resp.status_code == 404: - return None - resp.raise_for_status() - return resp.json() - - -# ── Block scanner ────────────────────────────────────────────────────────────── - - -async def scan_block( - height: int, - client: BlindBitOracleClient, - scan_secret_bytes: bytes, - spend_pub_bytes: bytes, - spend_secret_bytes: bytes, - labels: list[Label], # ← pre-computed, passed in -) -> list[OwnedUTXO]: - """Scan a single block. Labels are pre-computed outside the loop.""" - - # Try Compute Index first + async with self._client() as c: + r = await c.get(f"{self.base_url}/blockhash/{height}") + return None if r.status_code == 404 else r.json() + + +async def scan_block(height, client, scan_secret_bytes, spend_pub_bytes, spend_secret_bytes, labels): + if labels: + tweaks = await client.get_tweaks(height) + if not tweaks: return [] + utxos = await client.get_utxos(height) + if not utxos: return [] + owned = sync_block(tweaks, utxos, scan_secret_bytes, spend_pub_bytes, labels) + for o in owned: + if not o.timestamp: + o.timestamp = await get_block_ts(o.txid.hex()) + return owned compute_data = await client.get_compute_index(height) if compute_data: - matches = sync_block_from_compute_index( - compute_data["index"], - scan_secret_bytes, - spend_pub_bytes, - labels - ) + matches = sync_block_from_compute_index(compute_data["index"], scan_secret_bytes, spend_pub_bytes, labels) if matches: - # Only fetch full utxos if we have matches full_utxos = await client.get_utxos(height) - utxo_lookup = {u["pubkey"]: u for u in full_utxos if "pubkey" in u} + lkp = {u["pubkey"]: u for u in full_utxos if "pubkey" in u} for owned in matches: - pub_hex = owned.pub_key.hex() - full = utxo_lookup.get(pub_hex) - if not full: - # fallback: match by short prefix - short = pub_hex[:16] - full = next( - (u for u in full_utxos if u.get("pubkey", "")[:16] == short), - None - ) - if full: + ph = owned.pub_key.hex() + full = lkp.get(ph) or next((u for u in full_utxos if u.get("pubkey","")[:16]==ph[:16]), None) + if full: owned.vout = full.get("vout", owned.vout) owned.amount = full.get("amount", owned.amount) - owned.timestamp = await get_block_ts(full.get("txid")) - owned.utxo_state = "unspent" - owned.pub_key = bytes.fromhex(full["pubkey"]) + owned.timestamp = full.get("timestamp") or await get_block_ts(full.get("txid","")) + owned.pub_key = bytes.fromhex(full["pubkey"]) return matches - - # Fallback: separate tweaks + utxos tweaks = await client.get_tweaks(height) - if not tweaks: - return [] + if not tweaks: return [] utxos = await client.get_utxos(height) - if not utxos: - return [] + if not utxos: return [] return sync_block(tweaks, utxos, scan_secret_bytes, spend_pub_bytes, labels) -async def mark_spent_utxos_batch( - heights: list[int], - client: BlindBitOracleClient, - wallet_id: str, - owned_utxos_lookup: dict[str, dict], # txid:vout -> row — pre-fetched -) -> None: - """ - Check spent outputs for a batch of heights. - owned_utxos_lookup is pre-fetched once per scan batch. - """ +async def mark_spent_utxos_batch(heights, client, wallet_id, owned_utxos_lookup): if not owned_utxos_lookup: return @@ -664,253 +314,146 @@ async def check_height(height: int): spent_data = await client.get_spent_outputs(height) if not spent_data: return - spent_set = set(spent_data.get("index", [])) if not spent_set: return - block_utxos = await client.get_utxos(height) - utxo_pub_lookup = { - f"{u['txid']}:{u['vout']}": u.get("pubkey", "")[:16] - for u in block_utxos - } - - for lookup_key, row in owned_utxos_lookup.items(): - short_pub = utxo_pub_lookup.get(lookup_key, "") - if short_pub and short_pub in spent_set: + # spent-outputs index contains first 8 bytes of x-only pubkey + # of each spent output — match against our owned UTXOs pub_key + rows = await db.fetchall( + """SELECT txid, vout, pub_key FROM silnt.utxos + WHERE wallet_id = :wallet_id + AND utxo_state IN ('unspent', 'unconfirmed_spent')""", + {"wallet_id": wallet_id}, + ) + for row in rows: + short_pub = row["pub_key"][:16] # first 8 bytes = 16 hex chars + if short_pub in spent_set: await db.execute( """UPDATE silnt.utxos SET utxo_state = 'spent' WHERE txid = :txid AND vout = :vout AND wallet_id = :wallet_id""", - { - "txid": row["txid"], - "vout": row["vout"], - "wallet_id": wallet_id, - }, - ) - logger.info( - f"Marked UTXO {row['txid']}:{row['vout']} as spent at block {height}" + {"txid": row["txid"], "vout": row["vout"], "wallet_id": wallet_id}, ) + logger.info(f"Marked {row['txid']}:{row['vout']} spent at block {height}") except Exception as e: logger.warning(f"mark_spent_utxos error at block {height}: {e}") await asyncio.gather(*[check_height(h) for h in heights]) -# ── Last scan height ─────────────────────────────────────────────────────────── - - async def set_last_scan_height(wallet_id: str, height: int) -> None: - await db.execute( - "UPDATE silnt.wallets SET last_scan_height = :height WHERE id = :id", - {"height": height, "id": wallet_id}, - ) - - -# ── Main scan entry points ───────────────────────────────────────────────────── + await db.execute("UPDATE silnt.wallets SET last_scan_height = :height WHERE id = :id", + {"height": height, "id": wallet_id}) +def get_scan_progress(wallet_id: str) -> dict: + return _scan_progress.get(wallet_id, {"active": False, "current": 0, "total": 0, "found": 0}) -async def scan_wallet( - wallet_id: str, - from_height: Optional[int] = None, - to_height: Optional[int] = None, -) -> dict: - """ - Scan blockchain for UTXOs belonging to a wallet. - Stores found UTXOs in the DB and updates balance. +def set_scan_progress(wallet_id, current, total, found, active=True): + _scan_progress[wallet_id] = {"active": active, "current": current, "total": total, "found": found} - Args: - wallet_id: The silnt wallet ID - from_height: Start scanning from this block (default: wallet birth height) - to_height: Stop at this block (default: chain tip) - Returns: - dict with utxos_found, blocks_scanned, final_height - """ +async def scan_wallet(wallet_id: str, from_height: Optional[int] = None, to_height: Optional[int] = None) -> dict: wallet = await get_silnt_wallet(wallet_id) if not wallet: raise ValueError(f"Wallet {wallet_id} not found") - blindbit = await get_blindbit_config() if not blindbit.blindbit_url: raise ValueError("BlindBit Oracle URL not configured") - # ── Decrypt keys ────────────────────────────────────────────────────────── - scan_secret_encrypted = wallet.scan_secret - scan_secret_hex = await decrypt_secret(scan_secret_encrypted) + scan_secret_hex = await decrypt_secret(wallet.scan_secret) scan_secret_bytes = bytes.fromhex(scan_secret_hex) - - # Get spend key - row = await db.fetchone( - "SELECT spend_key FROM silnt.wallets WHERE id = :id", {"id": wallet_id} - ) + row = await db.fetchone("SELECT spend_key FROM silnt.wallets WHERE id = :id", {"id": wallet_id}) if not row or not row["spend_key"]: - raise ValueError(f"No spend key found for wallet {wallet_id}") - - spend_secret_hex = decrypt_spend_key(row["spend_key"], scan_secret_hex) - spend_secret_bytes = bytes.fromhex(spend_secret_hex) - spend_pub_bytes = coincurve.PublicKey.from_secret(spend_secret_bytes).format( - compressed=True - ) + raise ValueError(f"No spend key for wallet {wallet_id}") + spend_secret_bytes = bytes.fromhex(decrypt_spend_key(row["spend_key"], scan_secret_hex)) + spend_pub_bytes = coincurve.PublicKey.from_secret(spend_secret_bytes).format(compressed=True) - # ── Setup oracle client ─────────────────────────────────────────────────── oracle = BlindBitOracleClient(base_url=blindbit.blindbit_url) + start = max(from_height if from_height is not None else wallet.last_height, 1) + end = to_height if to_height is not None else await oracle.get_chain_tip() + logger.info(f"Scanning wallet {wallet_id} blocks {start}–{end}") - # ── Determine scan range ────────────────────────────────────────────────── - start = from_height if from_height is not None else wallet.last_height - if start < 1: - start = 1 - - chain_tip = await oracle.get_chain_tip() - end = to_height if to_height is not None else chain_tip - - logger.info(f"Scanning wallet {wallet_id} from block {start} to {end}") - - # ── Pre-compute labels ONCE ─────────────────────────────────────────────── saved_addresses = await get_wallet_addresses(wallet_id) - labels = create_labels( - scan_secret_bytes, - indices=[addr.label_index for addr in saved_addresses] - ) - logger.debug(f"Scanning with {len(labels)} label(s) for wallet {wallet_id}") + labels = create_labels(scan_secret_bytes, indices=[a.label_index for a in saved_addresses]) - # ── Scan blocks ─────────────────────────────────────────────────────────── total_found = 0 blocks_scanned = 0 last_scanned_height = start total_blocks = end - start + 1 - clear_scan_stop(wallet_id) # ← clear any previous stop request + clear_scan_stop(wallet_id) set_scan_progress(wallet_id, 0, total_blocks, 0) - - # ── Batch size for concurrent scanning ──────────────────────────────────── BATCH_SIZE = 30 - heights = list(range(start, end + 1)) - - for batch_start in range(0, len(heights), BATCH_SIZE): + for batch_start in range(0, total_blocks, BATCH_SIZE): if should_stop(wallet_id): - logger.info(f"Scan stopped by user at block {last_scanned_height}") + logger.info(f"Scan stopped at {last_scanned_height}") await set_last_scan_height(wallet_id, last_scanned_height) set_scan_progress(wallet_id, blocks_scanned, total_blocks, total_found, active=False) clear_scan_stop(wallet_id) break - batch = heights[batch_start:batch_start + BATCH_SIZE] + batch = list(range(start + batch_start, min(start + batch_start + BATCH_SIZE, end + 1))) - # ── Fetch pre-owned UTXOs for spent check (once per batch) ─────────── owned_rows = await db.fetchall( - """SELECT txid, vout FROM silnt.utxos - WHERE wallet_id = :wallet_id - AND utxo_state IN ('unspent', 'unconfirmed_spent')""", - {"wallet_id": wallet_id}, - ) - owned_utxos_lookup = { - f"{r['txid']}:{r['vout']}": r for r in owned_rows - } - - # ── Concurrent scan + spent check for batch ─────────────────────────── - scan_tasks = [ - scan_block( - height=h, - client=oracle, - scan_secret_bytes=scan_secret_bytes, - spend_pub_bytes=spend_pub_bytes, - spend_secret_bytes=spend_secret_bytes, - labels=labels, - ) - for h in batch - ] + "SELECT txid, vout FROM silnt.utxos WHERE wallet_id = :wallet_id AND utxo_state IN ('unspent', 'unconfirmed_spent')", + {"wallet_id": wallet_id}) + owned_utxos_lookup = {f"{r['txid']}:{r['vout']}": r for r in owned_rows} - batch_results = await asyncio.gather(*scan_tasks, return_exceptions=True) + batch_results = await asyncio.gather(*[ + scan_block(h, oracle, scan_secret_bytes, spend_pub_bytes, spend_secret_bytes, labels) + for h in batch], return_exceptions=True) - # Check spent UTXOs for the batch concurrently await mark_spent_utxos_batch(batch, oracle, wallet_id, owned_utxos_lookup) - # ── Process results ─────────────────────────────────────────────────── for h, result in zip(batch, batch_results): if isinstance(result, Exception): - logger.error(f"Error scanning block {h}: {result}") - continue - + logger.error(f"Block {h} error: {result}"); continue if result: await insert_utxos_for_wallet(wallet_id, result) total_found += len(result) - logger.info(f"Block {h}: stored {len(result)} UTXOs") - + logger.info(f"Block {h}: {len(result)} UTXOs") blocks_scanned += 1 last_scanned_height = h set_scan_progress(wallet_id, blocks_scanned, total_blocks, total_found) - - # Save progress every batch await set_last_scan_height(wallet_id, last_scanned_height) - - # ── Final update ────────────────────────────────────────────────────────── await set_last_scan_height(wallet_id, last_scanned_height) - set_scan_progress( - wallet_id, blocks_scanned, total_blocks, total_found, active=False - ) + set_scan_progress(wallet_id, blocks_scanned, total_blocks, total_found, active=False) - # Recalculate balance from unspent UTXOs - unspent_rows = await db.fetchall( + unspent = await db.fetchall( "SELECT amount FROM silnt.utxos WHERE wallet_id = :wallet_id AND utxo_state = 'unspent'", - {"wallet_id": wallet_id}, - ) - balance = sum(row["amount"] for row in unspent_rows) + {"wallet_id": wallet_id}) + balance = sum(r["amount"] for r in unspent) await update_balance(wallet_id, balance) - - logger.info( - f"Scan complete: {blocks_scanned} blocks, {total_found} Unspent UTXOs found, balance={balance} sats" - ) + logger.info(f"Scan done: {blocks_scanned} blocks, {total_found} UTXOs, balance={balance}") set_scan_progress(wallet_id, total_blocks, total_blocks, total_found, active=False) - return { - "utxos_found": total_found, - "blocks_scanned": blocks_scanned, - "final_height": last_scanned_height, - "balance": balance, - } + return {"utxos_found": total_found, "blocks_scanned": blocks_scanned, + "final_height": last_scanned_height, "balance": balance} async def scan_all_wallets(user: str, network: str = "mainnet") -> list[dict]: - """Scan all wallets for a given user.""" - wallets = await get_silnt_wallets(user, network) results = [] - for wallet in wallets: + for wallet in await get_silnt_wallets(user, network): try: - result = await scan_wallet(wallet.id) - result["wallet_id"] = wallet.id - results.append(result) + r = await scan_wallet(wallet.id) + r["wallet_id"] = wallet.id + results.append(r) except Exception as e: - logger.error(f"Failed to scan wallet {wallet.id}: {e}") + logger.error(f"Wallet {wallet.id} failed: {e}") results.append({"wallet_id": wallet.id, "error": str(e)}) return results -def get_scan_progress(wallet_id: str) -> dict: - return _scan_progress.get( - wallet_id, {"active": False, "current": 0, "total": 0, "found": 0} - ) - - -def set_scan_progress( - wallet_id: str, current: int, total: int, found: int, active: bool = True -): - _scan_progress[wallet_id] = { - "active": active, - "current": current, - "total": total, - "found": found, - } - -async def get_block_ts(txid) -> int: +async def get_block_ts(txid: str) -> int: blindbit = await get_blindbit_config() - mempool_base = (blindbit.mempool_url or "https://mempool.space").rstrip("/") - async with httpx.AsyncClient(timeout=10.0) as client: - resp = await client.get(f"{mempool_base}/api/tx/{txid}") - if resp.status_code == 200: - tx_data = resp.json() - ts = tx_data.get("status", {}).get("block_time") or 0 - if ts: - return int(ts) + base = (blindbit.mempool_url or "https://mempool.space").rstrip("/") + try: + async with httpx.AsyncClient(timeout=10.0) as c: + r = await c.get(f"{base}/api/tx/{txid}") + if r.status_code == 200: + return int(r.json().get("status", {}).get("block_time") or 0) + except Exception: + pass return 0 \ No newline at end of file diff --git a/helpers/wallet.py b/helpers/wallet.py index 1a03388..fabb432 100644 --- a/helpers/wallet.py +++ b/helpers/wallet.py @@ -3,6 +3,7 @@ import hashlib import httpx import io +import struct from base64 import b64encode from embit import bip32, bip39, ec, finalizer, script from embit.networks import NETWORKS @@ -503,35 +504,32 @@ def generate_labeled_sp_address( ) -> str: """ Derive a BIP352 labeled Silent Payment address. - B_m = B_spend + hash(b_scan || m) * G + B_m = B_spend + TaggedHash("BIP0352/Label", b_scan || ser32(m)) * G m=0 is reserved for change, user labels start at m=1 - """ - + """ scan_secret_bytes = bytes.fromhex(scan_secret_hex) spend_pub_bytes = bytes.fromhex(spend_pub_hex) - # hash("BIP0352/Label" || b_scan || m) - tag = b"BIP0352/Label" - tag_hash = hashlib.sha256(tag).digest() + # BIP352: TaggedHash("BIP0352/Label", scan_secret || ser32(m)) — big-endian + tag_hash = hashlib.sha256("BIP0352/Label".encode()).digest() label_hash = hashlib.sha256( - tag_hash + tag_hash + scan_secret_bytes + m.to_bytes(4, 'little') + tag_hash + tag_hash + scan_secret_bytes + struct.pack(">I", m) ).digest() # B_m = B_spend + label_hash * G - label_point = coincurve.PublicKey.from_secret(label_hash) - spend_pub = coincurve.PublicKey(spend_pub_bytes) - B_m = coincurve.PublicKey.combine_keys([spend_pub, label_point]) - B_m_bytes = B_m.format(compressed=True) + B_m = coincurve.PublicKey.combine_keys([ + coincurve.PublicKey(spend_pub_bytes), + coincurve.PublicKey.from_secret(label_hash), + ]).format(compressed=True) - # Encode as SP address: B_scan || B_m + # B_scan pubkey B_scan = coincurve.PublicKey.from_secret(scan_secret_bytes).format(compressed=True) - - address = bech32_encode( + + return bech32_encode( hrp, - [0] + convertbits(B_scan + B_m_bytes, 8, 5), + [0] + convertbits(B_scan + B_m, 8, 5), Encoding.BECH32M ) - return address def get_spend_pub_from_secret(spend_secret_hex: str) -> str: From 08feb619a59bf49226fb3aace52af252adfb897e Mon Sep 17 00:00:00 2001 From: Ponthief Date: Sun, 3 May 2026 23:29:34 +0100 Subject: [PATCH 50/83] change encrypt decrypt algo --- crud.py | 52 +++--- helpers/curve.py | 5 - helpers/scan.py | 346 ++++++++++++++++++++++++++++--------- helpers/wallet.py | 130 ++++++++------ migrations.py | 3 +- models.py | 11 +- static/js/index.js | 14 +- templates/silnt/index.html | 35 ++-- views_api.py | 139 ++++++++------- 9 files changed, 478 insertions(+), 257 deletions(-) diff --git a/crud.py b/crud.py index 7103ee7..f61258f 100644 --- a/crud.py +++ b/crud.py @@ -134,23 +134,6 @@ async def get_spend_key(wallet_id: str) -> Optional[str]: return row["spend_key"] if row else None -async def get_or_create_server_secret() -> str: - row = await db.fetchone( - "SELECT json_data FROM silnt.blindbit_config WHERE id = :id", - {"id": SILNT_SECRET_ID}, - ) - if row: - return json.loads(row["json_data"])["secret"] - - # Generate new secret on first use - server_secret = secrets.token_hex(32) - await db.execute( - "INSERT INTO silnt.blindbit_config (id, json_data) VALUES (:id, :json_data)", - {"id": SILNT_SECRET_ID, "json_data": json.dumps({"secret": server_secret})}, - ) - return server_secret - - async def get_utxos_for_wallet(wallet_id: str) -> list[UTXORecord]: return await db.fetchall( "SELECT * FROM silnt.utxos WHERE wallet_id = :wallet_id ORDER BY timestamp DESC", @@ -159,8 +142,8 @@ async def get_utxos_for_wallet(wallet_id: str) -> list[UTXORecord]: ) -async def insert_utxos_for_wallet(wallet_id: str, utxos: list) -> None: - for utxo in utxos: +async def insert_utxos_for_wallet(wallet_id: str, utxos: list) -> None: + for utxo in utxos: await db.execute( """INSERT INTO silnt.utxos (txid, vout, amount, priv_key_tweak, pub_key, utxo_state, timestamp, wallet_id) VALUES (:txid, :vout, :amount, :priv_key_tweak, :pub_key, :utxo_state, :timestamp, :wallet_id) @@ -173,14 +156,16 @@ async def insert_utxos_for_wallet(wallet_id: str, utxos: list) -> None: THEN silnt.utxos.utxo_state ELSE EXCLUDED.utxo_state END""", - utxo.to_db_row(wallet_id) - ) + utxo.to_db_row(wallet_id), + ) + async def update_unconfirmed_utxo(wallet_id: str, txid: str): - await db.execute( - "UPDATE silnt.utxos SET utxo_state = 'unconfirmed_spent' WHERE txid = :txid AND wallet_id = :wallet_id", - {"txid": txid, "wallet_id": wallet_id} - ) + await db.execute( + "UPDATE silnt.utxos SET utxo_state = 'unconfirmed_spent' WHERE txid = :txid AND wallet_id = :wallet_id", + {"txid": txid, "wallet_id": wallet_id}, + ) + async def get_wallet_addresses(wallet_id: str) -> list: return await db.fetchall( @@ -188,6 +173,7 @@ async def get_wallet_addresses(wallet_id: str) -> list: {"wallet_id": wallet_id}, ) + async def count_wallet_addresses(wallet_id: str) -> int: row = await db.fetchone( "SELECT COUNT(*) as cnt FROM silnt.wallet_addresses WHERE wallet_id = :wallet_id", @@ -195,7 +181,10 @@ async def count_wallet_addresses(wallet_id: str) -> int: ) return row["cnt"] if row else 0 -async def insert_wallet_address(wallet_id: str, sp_address: str, label_index: int, address_id) -> None: + +async def insert_wallet_address( + wallet_id: str, sp_address: str, label_index: int, address_id +) -> None: await db.execute( """INSERT INTO silnt.wallet_addresses (id, wallet_id, sp_address, label_index, created_at) VALUES (:id, :wallet_id, :sp_address, :label_index, :created_at)""", @@ -204,24 +193,25 @@ async def insert_wallet_address(wallet_id: str, sp_address: str, label_index: in "wallet_id": wallet_id, "sp_address": sp_address, "label_index": label_index, - "created_at": int(time.time()) - } + "created_at": int(time.time()), + }, ) - -async def delete_wallet_addresses(wallet_id: str) -> None: +async def delete_wallet_label_addresses(wallet_id: str) -> None: await db.execute( "DELETE FROM silnt.wallet_addresses WHERE wallet_id = :wallet_id", {"wallet_id": wallet_id}, ) -async def delete_wallet_address(address_id: str, wallet_id: str) -> None: + +async def delete_wallet_label_address(address_id: str, wallet_id: str) -> None: await db.execute( "DELETE FROM silnt.wallet_addresses WHERE id = :id AND wallet_id = :wallet_id", {"id": address_id, "wallet_id": wallet_id}, ) + # ── Global admin-only blindbit config ─────────────────────────────────────── diff --git a/helpers/curve.py b/helpers/curve.py index e223c22..4160efc 100644 --- a/helpers/curve.py +++ b/helpers/curve.py @@ -102,11 +102,6 @@ def bytes_from_point(P: Point) -> bytes: return bytes_from_int(x(P)) -# Get bytes from a hex -# def bytes_from_hex(a: str) -> bytes: -# return unhexlify(a) - - def convertbits( data: bytes, frombits: int, tobits: int, pad: bool = True ) -> Optional[list[int]]: diff --git a/helpers/scan.py b/helpers/scan.py index 4fcbe86..da2349c 100644 --- a/helpers/scan.py +++ b/helpers/scan.py @@ -1,6 +1,7 @@ """ scan.py — Silent Payments blockchain scanner for the silnt LNbits extension. """ + from __future__ import annotations import asyncio, hashlib, struct from dataclasses import dataclass @@ -8,8 +9,16 @@ import coincurve, httpx from coincurve import PublicKey from loguru import logger -from ..crud import db, get_blindbit_config, get_silnt_wallet, get_silnt_wallets, get_wallet_addresses, insert_utxos_for_wallet, update_balance -from .wallet import decrypt_secret, decrypt_spend_key +from ..crud import ( + db, + get_blindbit_config, + get_silnt_wallet, + get_silnt_wallets, + get_wallet_addresses, + insert_utxos_for_wallet, + update_balance, +) +from .wallet import decrypt_for_wallet _scan_progress: dict[str, dict] = {} _scan_stop: dict[str, bool] = {} @@ -23,12 +32,14 @@ class Label: address: str = "" m: int = 0 + @dataclass class FoundOutput: output: bytes sec_key_tweak: bytes label: Optional[Label] = None + @dataclass class OwnedUTXO: txid: bytes @@ -41,46 +52,81 @@ class OwnedUTXO: label: Optional[Label] = None def to_db_row(self, wallet_id: str) -> dict: - return {"txid": self.txid.hex(), "vout": self.vout, "amount": self.amount, - "priv_key_tweak": self.priv_key_tweak.hex(), "pub_key": self.pub_key.hex(), - "utxo_state": self.utxo_state, "timestamp": self.timestamp, "wallet_id": wallet_id} + return { + "txid": self.txid.hex(), + "vout": self.vout, + "amount": self.amount, + "priv_key_tweak": self.priv_key_tweak.hex(), + "pub_key": self.pub_key.hex(), + "utxo_state": self.utxo_state, + "timestamp": self.timestamp, + "wallet_id": wallet_id, + } + + +def request_scan_stop(wallet_id: str): + _scan_stop[wallet_id] = True -def request_scan_stop(wallet_id: str): _scan_stop[wallet_id] = True -def should_stop(wallet_id: str) -> bool: return _scan_stop.get(wallet_id, False) -def clear_scan_stop(wallet_id: str): _scan_stop.pop(wallet_id, None) +def should_stop(wallet_id: str) -> bool: + return _scan_stop.get(wallet_id, False) + + +def clear_scan_stop(wallet_id: str): + _scan_stop.pop(wallet_id, None) def _tagged_hash(tag: str, data: bytes) -> bytes: h = hashlib.sha256(tag.encode()).digest() return hashlib.sha256(h + h + data).digest() + def _ser_u32(k: int) -> bytes: return struct.pack(">I", k) -def create_shared_secret(public_component: bytes, scan_key: bytes, input_hash: Optional[bytes] = None) -> bytes: + +def create_shared_secret( + public_component: bytes, scan_key: bytes, input_hash: Optional[bytes] = None +) -> bytes: if input_hash is not None: - scalar = (int.from_bytes(scan_key, "big") * int.from_bytes(input_hash, "big")) % SECP256K1_N + scalar = ( + int.from_bytes(scan_key, "big") * int.from_bytes(input_hash, "big") + ) % SECP256K1_N effective_key = scalar.to_bytes(32, "big") else: effective_key = scan_key return PublicKey(public_component).multiply(effective_key).format(compressed=True) -def create_output_pub_key_and_tweak(shared_secret: bytes, spend_pub_key: bytes, k: int) -> tuple[bytes, bytes]: + +def create_output_pub_key_and_tweak( + shared_secret: bytes, spend_pub_key: bytes, k: int +) -> tuple[bytes, bytes]: t_k = _tagged_hash("BIP0352/SharedSecret", shared_secret + _ser_u32(k)) - p_k = PublicKey(spend_pub_key).combine([PublicKey.from_secret(t_k)]).format(compressed=True) + p_k = ( + PublicKey(spend_pub_key) + .combine([PublicKey.from_secret(t_k)]) + .format(compressed=True) + ) return p_k[1:], t_k + def add_public_keys(pk1: bytes, pk2: bytes) -> bytes: - if isinstance(pk1, PublicKey): pk1 = pk1.format(compressed=True) - if isinstance(pk2, PublicKey): pk2 = pk2.format(compressed=True) + if isinstance(pk1, PublicKey): + pk1 = pk1.format(compressed=True) + if isinstance(pk2, PublicKey): + pk2 = pk2.format(compressed=True) return PublicKey(pk1).combine([PublicKey(pk2)]).format(compressed=True) + def negate_public_key(pk: bytes) -> bytes: return bytes([0x02 if pk[0] == 0x03 else 0x03]) + pk[1:] + def add_private_keys(sk1: bytes, sk2: bytes) -> bytes: - return ((int.from_bytes(sk1, "big") + int.from_bytes(sk2, "big")) % SECP256K1_N).to_bytes(32, "big") + return ( + (int.from_bytes(sk1, "big") + int.from_bytes(sk2, "big")) % SECP256K1_N + ).to_bytes(32, "big") + def create_label(scan_key: bytes, m: int) -> Label: tweak = _tagged_hash("BIP0352/Label", scan_key + _ser_u32(m)) @@ -90,12 +136,18 @@ def create_label(scan_key: bytes, m: int) -> Label: # tweak = hashlib.sha256( # tag_hash + tag_hash + scan_key + m.to_bytes(4, 'little') # ).digest() - return Label(pub_key=PublicKey.from_secret(tweak).format(compressed=True), tweak=tweak, m=m) + return Label( + pub_key=PublicKey.from_secret(tweak).format(compressed=True), tweak=tweak, m=m + ) + def create_labels(scan_key: bytes, indices: list[int]) -> list[Label]: return [create_label(scan_key, m) for m in sorted(set([0] + indices))] -def match_labels(tx_output_33: bytes, pk_33: bytes, labels: list[Label]) -> Optional[Label]: + +def match_labels( + tx_output_33: bytes, pk_33: bytes, labels: list[Label] +) -> Optional[Label]: try: diff = add_public_keys(tx_output_33, negate_public_key(pk_33)) except Exception: @@ -105,52 +157,87 @@ def match_labels(tx_output_33: bytes, pk_33: bytes, labels: list[Label]) -> Opti return label return None + def receiver_scan_transaction_with_shared_secret( - scan_key: bytes, spend_pub_key: bytes, labels: list[Label], - tx_outputs: list[bytes], shared_secret: bytes, + scan_key: bytes, + spend_pub_key: bytes, + labels: list[Label], + tx_outputs: list[bytes], + shared_secret: bytes, ) -> list[FoundOutput]: found_outputs: list[FoundOutput] = [] remaining = list(tx_outputs) k = 0 while True: - output_pub_key, tweak = create_output_pub_key_and_tweak(shared_secret, spend_pub_key, k) + output_pub_key, tweak = create_output_pub_key_and_tweak( + shared_secret, spend_pub_key, k + ) found = False for i, tx_output in enumerate(remaining): if output_pub_key == tx_output: found_outputs.append(FoundOutput(output=tx_output, sec_key_tweak=tweak)) - remaining.pop(i); found = True; k += 1; break + remaining.pop(i) + found = True + k += 1 + break if not labels: continue tx_out_33 = b"\x02" + tx_output out_pk_33 = b"\x02" + output_pub_key fl = match_labels(tx_out_33, out_pk_33, labels) if fl: - found_outputs.append(FoundOutput(output=tx_output, sec_key_tweak=add_private_keys(tweak, fl.tweak), label=fl)) - remaining.pop(i); found = True; k += 1; break + found_outputs.append( + FoundOutput( + output=tx_output, + sec_key_tweak=add_private_keys(tweak, fl.tweak), + label=fl, + ) + ) + remaining.pop(i) + found = True + k += 1 + break tx_out_neg = negate_public_key(tx_out_33) fl = match_labels(tx_out_neg, out_pk_33, labels) if fl: - found_outputs.append(FoundOutput(output=tx_out_neg[1:], sec_key_tweak=add_private_keys(tweak, fl.tweak), label=fl)) - remaining.pop(i); found = True; k += 1; break + found_outputs.append( + FoundOutput( + output=tx_out_neg[1:], + sec_key_tweak=add_private_keys(tweak, fl.tweak), + label=fl, + ) + ) + remaining.pop(i) + found = True + k += 1 + break if not found: break return found_outputs -def receiver_scan_transaction(scan_key, spend_pub_key, labels, tx_outputs, public_component, input_hash): + +def receiver_scan_transaction( + scan_key, spend_pub_key, labels, tx_outputs, public_component, input_hash +): return receiver_scan_transaction_with_shared_secret( - scan_key, spend_pub_key, labels, tx_outputs, - create_shared_secret(public_component, scan_key, input_hash)) + scan_key, + spend_pub_key, + labels, + tx_outputs, + create_shared_secret(public_component, scan_key, input_hash), + ) + def sync_block(tweaks, utxos, scan_key, spend_pub_key, labels): tweak_script_map: dict[bytes, tuple[bytes, bytes]] = {} raw = tweaks[0] tweak = bytes.fromhex(raw) if isinstance(raw, str) else raw ss = create_shared_secret(tweak, scan_key) - opk, _ = create_output_pub_key_and_tweak(ss, spend_pub_key, 0) + opk, _ = create_output_pub_key_and_tweak(ss, spend_pub_key, 0) for raw in tweaks: tweak = bytes.fromhex(raw) if isinstance(raw, str) else raw ss = create_shared_secret(tweak, scan_key) - opk, _ = create_output_pub_key_and_tweak(ss, spend_pub_key, 0) + opk, _ = create_output_pub_key_and_tweak(ss, spend_pub_key, 0) tweak_script_map[opk] = (tweak, opk) b33 = b"\x02" + opk for label in labels: @@ -172,24 +259,40 @@ def sync_block(tweaks, utxos, scan_key, spend_pub_key, labels): tb = bytes.fromhex(u["txid"]) xo = bytes.fromhex(u["pubkey"]) txid_groups.setdefault(tb, []).append(u) - helper_mapping[xo] = tb + helper_mapping[xo] = tb to_check: dict[bytes, list[dict]] = {} for xo, (tw, _) in tweak_script_map.items(): if xo in helper_mapping: to_check[tw] = txid_groups[helper_mapping[xo]] owned: list[OwnedUTXO] = [] for tw, rel_utxos in to_check.items(): - found = receiver_scan_transaction(scan_key, spend_pub_key, labels, - [bytes.fromhex(u["pubkey"]) for u in rel_utxos], tw, None) + found = receiver_scan_transaction( + scan_key, + spend_pub_key, + labels, + [bytes.fromhex(u["pubkey"]) for u in rel_utxos], + tw, + None, + ) for fo in found: for u in rel_utxos: if fo.output == bytes.fromhex(u["pubkey"]): - owned.append(OwnedUTXO(txid=bytes.fromhex(u["txid"]), vout=u["vout"], - amount=u["amount"], priv_key_tweak=fo.sec_key_tweak, pub_key=fo.output, - utxo_state="unspent", timestamp=u.get("timestamp", 0), label=fo.label)) + owned.append( + OwnedUTXO( + txid=bytes.fromhex(u["txid"]), + vout=u["vout"], + amount=u["amount"], + priv_key_tweak=fo.sec_key_tweak, + pub_key=fo.output, + utxo_state="unspent", + timestamp=u.get("timestamp", 0), + label=fo.label, + ) + ) break return owned + def sync_block_from_compute_index(index, scan_key, spend_pub_key, labels): owned: list[OwnedUTXO] = [] for entry in index: @@ -206,8 +309,16 @@ def sync_block_from_compute_index(index, scan_key, spend_pub_key, labels): opk, t_k = create_output_pub_key_and_tweak(ss, spend_pub_key, k) matched = False if opk.hex()[:16] in shorts: - owned.append(OwnedUTXO(txid=bytes.fromhex(txid), vout=0, amount=0, - priv_key_tweak=t_k, pub_key=opk, utxo_state="unspent")) + owned.append( + OwnedUTXO( + txid=bytes.fromhex(txid), + vout=0, + amount=0, + priv_key_tweak=t_k, + pub_key=opk, + utxo_state="unspent", + ) + ) matched = True if labels: b33 = b"\x02" + opk @@ -215,9 +326,19 @@ def sync_block_from_compute_index(index, scan_key, spend_pub_key, labels): try: lo = add_public_keys(b33, label.pub_key) if lo[1:].hex()[:16] in shorts: - owned.append(OwnedUTXO(txid=bytes.fromhex(txid), vout=0, amount=0, - priv_key_tweak=add_private_keys(t_k, label.tweak), - pub_key=lo[1:], utxo_state="unspent", label=label)) + owned.append( + OwnedUTXO( + txid=bytes.fromhex(txid), + vout=0, + amount=0, + priv_key_tweak=add_private_keys( + t_k, label.tweak + ), + pub_key=lo[1:], + utxo_state="unspent", + label=label, + ) + ) matched = True except Exception: pass @@ -245,7 +366,9 @@ async def get_tweaks(self, height: int) -> list[bytes]: r = await c.get(f"{self.base_url}/tweaks/{height}") r.raise_for_status() d = r.json() - return [bytes.fromhex(t) for t in (d["index"] if isinstance(d, dict) else d)] + return [ + bytes.fromhex(t) for t in (d["index"] if isinstance(d, dict) else d) + ] async def get_utxos(self, height: int) -> list[dict]: async with self._client() as c: @@ -262,7 +385,8 @@ async def get_spent_outputs(self, height: int) -> Optional[dict]: async def get_compute_index(self, height: int) -> Optional[dict]: async with self._client() as c: r = await c.get(f"{self.base_url}/compute-index/{height}") - if r.status_code == 404: return None + if r.status_code == 404: + return None d = r.json() return d if isinstance(d, dict) and "index" in d else {"index": d} @@ -272,12 +396,16 @@ async def get_block_hash(self, height: int) -> Optional[dict]: return None if r.status_code == 404 else r.json() -async def scan_block(height, client, scan_secret_bytes, spend_pub_bytes, spend_secret_bytes, labels): +async def scan_block( + height, client, scan_secret_bytes, spend_pub_bytes, spend_secret_bytes, labels +): if labels: tweaks = await client.get_tweaks(height) - if not tweaks: return [] + if not tweaks: + return [] utxos = await client.get_utxos(height) - if not utxos: return [] + if not utxos: + return [] owned = sync_block(tweaks, utxos, scan_secret_bytes, spend_pub_bytes, labels) for o in owned: if not o.timestamp: @@ -285,23 +413,31 @@ async def scan_block(height, client, scan_secret_bytes, spend_pub_bytes, spend_s return owned compute_data = await client.get_compute_index(height) if compute_data: - matches = sync_block_from_compute_index(compute_data["index"], scan_secret_bytes, spend_pub_bytes, labels) + matches = sync_block_from_compute_index( + compute_data["index"], scan_secret_bytes, spend_pub_bytes, labels + ) if matches: full_utxos = await client.get_utxos(height) lkp = {u["pubkey"]: u for u in full_utxos if "pubkey" in u} for owned in matches: ph = owned.pub_key.hex() - full = lkp.get(ph) or next((u for u in full_utxos if u.get("pubkey","")[:16]==ph[:16]), None) + full = lkp.get(ph) or next( + (u for u in full_utxos if u.get("pubkey", "")[:16] == ph[:16]), None + ) if full: owned.vout = full.get("vout", owned.vout) owned.amount = full.get("amount", owned.amount) - owned.timestamp = full.get("timestamp") or await get_block_ts(full.get("txid","")) + owned.timestamp = full.get("timestamp") or await get_block_ts( + full.get("txid", "") + ) owned.pub_key = bytes.fromhex(full["pubkey"]) return matches tweaks = await client.get_tweaks(height) - if not tweaks: return [] + if not tweaks: + return [] utxos = await client.get_utxos(height) - if not utxos: return [] + if not utxos: + return [] return sync_block(tweaks, utxos, scan_secret_bytes, spend_pub_bytes, labels) @@ -333,9 +469,15 @@ async def check_height(height: int): """UPDATE silnt.utxos SET utxo_state = 'spent' WHERE txid = :txid AND vout = :vout AND wallet_id = :wallet_id""", - {"txid": row["txid"], "vout": row["vout"], "wallet_id": wallet_id}, + { + "txid": row["txid"], + "vout": row["vout"], + "wallet_id": wallet_id, + }, + ) + logger.info( + f"Marked {row['txid']}:{row['vout']} spent at block {height}" ) - logger.info(f"Marked {row['txid']}:{row['vout']} spent at block {height}") except Exception as e: logger.warning(f"mark_spent_utxos error at block {height}: {e}") @@ -343,17 +485,33 @@ async def check_height(height: int): async def set_last_scan_height(wallet_id: str, height: int) -> None: - await db.execute("UPDATE silnt.wallets SET last_scan_height = :height WHERE id = :id", - {"height": height, "id": wallet_id}) + await db.execute( + "UPDATE silnt.wallets SET last_scan_height = :height WHERE id = :id", + {"height": height, "id": wallet_id}, + ) -def get_scan_progress(wallet_id: str) -> dict: - return _scan_progress.get(wallet_id, {"active": False, "current": 0, "total": 0, "found": 0}) -def set_scan_progress(wallet_id, current, total, found, active=True): - _scan_progress[wallet_id] = {"active": active, "current": current, "total": total, "found": found} +def get_scan_progress(wallet_id: str) -> dict: + return _scan_progress.get( + wallet_id, {"active": False, "current": 0, "total": 0, "found": 0} + ) -async def scan_wallet(wallet_id: str, from_height: Optional[int] = None, to_height: Optional[int] = None) -> dict: +def set_scan_progress(wallet_id, current, total, found, active=True): + _scan_progress[wallet_id] = { + "active": active, + "current": current, + "total": total, + "found": found, + } + + +async def scan_wallet( + wallet_id: str, + adminkey: str, + from_height: Optional[int] = None, + to_height: Optional[int] = None, +) -> dict: wallet = await get_silnt_wallet(wallet_id) if not wallet: raise ValueError(f"Wallet {wallet_id} not found") @@ -361,13 +519,13 @@ async def scan_wallet(wallet_id: str, from_height: Optional[int] = None, to_heig if not blindbit.blindbit_url: raise ValueError("BlindBit Oracle URL not configured") - scan_secret_hex = await decrypt_secret(wallet.scan_secret) + scan_secret_hex = decrypt_for_wallet(wallet.scan_secret, adminkey, wallet_id) + spend_secret_hex = decrypt_for_wallet(wallet.spend_key, adminkey, wallet_id) scan_secret_bytes = bytes.fromhex(scan_secret_hex) - row = await db.fetchone("SELECT spend_key FROM silnt.wallets WHERE id = :id", {"id": wallet_id}) - if not row or not row["spend_key"]: - raise ValueError(f"No spend key for wallet {wallet_id}") - spend_secret_bytes = bytes.fromhex(decrypt_spend_key(row["spend_key"], scan_secret_hex)) - spend_pub_bytes = coincurve.PublicKey.from_secret(spend_secret_bytes).format(compressed=True) + spend_secret_bytes = bytes.fromhex(spend_secret_hex) + spend_pub_bytes = coincurve.PublicKey.from_secret(spend_secret_bytes).format( + compressed=True + ) oracle = BlindBitOracleClient(base_url=blindbit.blindbit_url) start = max(from_height if from_height is not None else wallet.last_height, 1) @@ -375,7 +533,9 @@ async def scan_wallet(wallet_id: str, from_height: Optional[int] = None, to_heig logger.info(f"Scanning wallet {wallet_id} blocks {start}–{end}") saved_addresses = await get_wallet_addresses(wallet_id) - labels = create_labels(scan_secret_bytes, indices=[a.label_index for a in saved_addresses]) + labels = create_labels( + scan_secret_bytes, indices=[a.label_index for a in saved_addresses] + ) total_found = 0 blocks_scanned = 0 @@ -389,26 +549,43 @@ async def scan_wallet(wallet_id: str, from_height: Optional[int] = None, to_heig if should_stop(wallet_id): logger.info(f"Scan stopped at {last_scanned_height}") await set_last_scan_height(wallet_id, last_scanned_height) - set_scan_progress(wallet_id, blocks_scanned, total_blocks, total_found, active=False) + set_scan_progress( + wallet_id, blocks_scanned, total_blocks, total_found, active=False + ) clear_scan_stop(wallet_id) break - batch = list(range(start + batch_start, min(start + batch_start + BATCH_SIZE, end + 1))) + batch = list( + range(start + batch_start, min(start + batch_start + BATCH_SIZE, end + 1)) + ) owned_rows = await db.fetchall( "SELECT txid, vout FROM silnt.utxos WHERE wallet_id = :wallet_id AND utxo_state IN ('unspent', 'unconfirmed_spent')", - {"wallet_id": wallet_id}) + {"wallet_id": wallet_id}, + ) owned_utxos_lookup = {f"{r['txid']}:{r['vout']}": r for r in owned_rows} - batch_results = await asyncio.gather(*[ - scan_block(h, oracle, scan_secret_bytes, spend_pub_bytes, spend_secret_bytes, labels) - for h in batch], return_exceptions=True) + batch_results = await asyncio.gather( + *[ + scan_block( + h, + oracle, + scan_secret_bytes, + spend_pub_bytes, + spend_secret_bytes, + labels, + ) + for h in batch + ], + return_exceptions=True, + ) await mark_spent_utxos_batch(batch, oracle, wallet_id, owned_utxos_lookup) for h, result in zip(batch, batch_results): if isinstance(result, Exception): - logger.error(f"Block {h} error: {result}"); continue + logger.error(f"Block {h} error: {result}") + continue if result: await insert_utxos_for_wallet(wallet_id, result) total_found += len(result) @@ -420,17 +597,26 @@ async def scan_wallet(wallet_id: str, from_height: Optional[int] = None, to_heig await set_last_scan_height(wallet_id, last_scanned_height) await set_last_scan_height(wallet_id, last_scanned_height) - set_scan_progress(wallet_id, blocks_scanned, total_blocks, total_found, active=False) + set_scan_progress( + wallet_id, blocks_scanned, total_blocks, total_found, active=False + ) unspent = await db.fetchall( "SELECT amount FROM silnt.utxos WHERE wallet_id = :wallet_id AND utxo_state = 'unspent'", - {"wallet_id": wallet_id}) + {"wallet_id": wallet_id}, + ) balance = sum(r["amount"] for r in unspent) await update_balance(wallet_id, balance) - logger.info(f"Scan done: {blocks_scanned} blocks, {total_found} UTXOs, balance={balance}") + logger.info( + f"Scan done: {blocks_scanned} blocks, {total_found} UTXOs, balance={balance}" + ) set_scan_progress(wallet_id, total_blocks, total_blocks, total_found, active=False) - return {"utxos_found": total_found, "blocks_scanned": blocks_scanned, - "final_height": last_scanned_height, "balance": balance} + return { + "utxos_found": total_found, + "blocks_scanned": blocks_scanned, + "final_height": last_scanned_height, + "balance": balance, + } async def scan_all_wallets(user: str, network: str = "mainnet") -> list[dict]: @@ -456,4 +642,4 @@ async def get_block_ts(txid: str) -> int: return int(r.json().get("status", {}).get("block_time") or 0) except Exception: pass - return 0 \ No newline at end of file + return 0 diff --git a/helpers/wallet.py b/helpers/wallet.py index fabb432..0948582 100644 --- a/helpers/wallet.py +++ b/helpers/wallet.py @@ -2,7 +2,9 @@ import coincurve import hashlib import httpx +import hmac import io +import math import struct from base64 import b64encode from embit import bip32, bip39, ec, finalizer, script @@ -11,7 +13,8 @@ from .curve import bech32_encode, Encoding from .curve import pubkey_point_gen_from_int, int_from_bytes, Point from loguru import logger -from ..crud import get_or_create_server_secret + +# from ..crud import get_or_create_server_secret from lnbits.utils.crypto import AESCipher from cryptography.fernet import Fernet from embit.transaction import ( @@ -40,20 +43,42 @@ from embit.ec import SchnorrSig +# ── New adminkey-based encryption (add after existing Fernet imports) ───────── + + +def derive_wallet_key(adminkey: str, wallet_id: str) -> bytes: + """Derive a per-wallet 32-byte key from adminkey + wallet_id via HMAC-SHA256. + Never stored — must be re-derived on every use from the caller's adminkey.""" + return hmac.new( + adminkey.encode(), msg=wallet_id.encode(), digestmod=hashlib.sha256 + ).digest() + + +def encrypt_for_wallet(plaintext: str, adminkey: str, wallet_id: str) -> str: + """Fernet-encrypt a string using a key derived from adminkey + wallet_id.""" + key = base64.urlsafe_b64encode(derive_wallet_key(adminkey, wallet_id)) + return Fernet(key).encrypt(plaintext.encode()).decode() + + +def decrypt_for_wallet(encrypted: str, adminkey: str, wallet_id: str) -> str: + """Fernet-decrypt a value produced by encrypt_for_wallet.""" + key = base64.urlsafe_b64encode(derive_wallet_key(adminkey, wallet_id)) + return Fernet(key).decrypt(encrypted.encode()).decode() + -def encrypt_spend_key(spend_priv_hex: str, scan_key_hex: str) -> str: - # Derive a 32-byte Fernet key from scan_key_hex - key_bytes = hashlib.sha256(scan_key_hex.encode()).digest() - fernet_key = base64.urlsafe_b64encode(key_bytes) - f = Fernet(fernet_key) - return f.encrypt(spend_priv_hex.encode()).decode() +# def encrypt_spend_key(spend_priv_hex: str, scan_key_hex: str) -> str: +# # Derive a 32-byte Fernet key from scan_key_hex +# key_bytes = hashlib.sha256(scan_key_hex.encode()).digest() +# fernet_key = base64.urlsafe_b64encode(key_bytes) +# f = Fernet(fernet_key) +# return f.encrypt(spend_priv_hex.encode()).decode() -def decrypt_spend_key(encrypted: str, scan_key_hex: str) -> str: - key_bytes = hashlib.sha256(scan_key_hex.encode()).digest() - fernet_key = base64.urlsafe_b64encode(key_bytes) - f = Fernet(fernet_key) - return f.decrypt(encrypted.encode()).decode() +# def decrypt_spend_key(encrypted: str, scan_key_hex: str) -> str: +# key_bytes = hashlib.sha256(scan_key_hex.encode()).digest() +# fernet_key = base64.urlsafe_b64encode(key_bytes) +# f = Fernet(fernet_key) +# return f.decrypt(encrypted.encode()).decode() def get_seed(mnemonic) -> bytes: @@ -104,10 +129,10 @@ async def generate_silent_wallet_address(mnemonic) -> tuple: # Encrypt spend private key using scan key as encryption key spend_priv_hex = hexlify(key_material["spend_priv_key"]).decode() scan_key_hex = key_material["scank"] - encrypted_spend_key = encrypt_spend_key(spend_priv_hex, scan_key_hex) - # Encrypt scan secret using server secret - encrypted_scan_secret = await encrypt_secret(scan_key_hex) - return (str(sp), encrypted_scan_secret, str(encrypted_spend_key)) + # encrypted_spend_key = encrypt_spend_key(spend_priv_hex, scan_key_hex) + # # Encrypt scan secret using server secret + # encrypted_scan_secret = await encrypt_secret(scan_key_hex) + return (str(sp), scan_key_hex, spend_priv_hex) def parse_sp_address(sp_address: str) -> tuple: @@ -216,7 +241,7 @@ def build_transaction( spend_key_hex: str, recipient: str, amount: int, - fee_rate: int, + fee_rate: float, utxos: list[dict], network: str = "Mainnet", ) -> dict: @@ -281,15 +306,32 @@ def build_transaction( total_input = sum(u["amount"] for u in utxos) # Estimate vsize: 10 base + 57.5 per taproot input + 31 per output estimated_vsize = int(10 + (57.5 * len(utxos)) + (31 * 2)) - fee = estimated_vsize * fee_rate + # Round up to nearest sat — floor would underpay, ceil ensures broadcast + fee = max(1, math.ceil(estimated_vsize * fee_rate)) + # fee = estimated_vsize * fee_rate change_amount = total_input - amount - fee - if change_amount < 0: raise ValueError( f"Insufficient funds. Need {amount + fee} sats " f"(including {fee} sats fee), have {total_input} sats." ) + # If change is below dust threshold, try two strategies: + if 0 < change_amount < 546: + # Strategy 1: reduce amount to make change viable + reduced_amount = amount - (546 - change_amount) + if reduced_amount >= 546: + change_amount = total_input - reduced_amount - fee + amount = reduced_amount + logger.debug( + f"Adjusted amount to {amount} sats to avoid dust change " + f"— change now {change_amount} sats" + ) + else: + # Strategy 2: add dust to fee — can't reduce amount further + logger.debug(f"Change {change_amount} sats below dust — adding to fee") + fee += change_amount + change_amount = 0 # ── 5. Build inputs ─────────────────────────────────────────────────── tx_inputs_with_keys = [ ( @@ -312,7 +354,7 @@ def build_transaction( # ── 6. Build outputs ────────────────────────────────────────────────── tx_outputs = [TransactionOutput(amount, recipient_script)] - if change_amount > 546: + if change_amount >= 546: change_script = input_scripts_sorted[0][0] tx_outputs.append(TransactionOutput(change_amount, change_script)) @@ -375,9 +417,11 @@ def build_transaction( "tx_hex": tx_hex, "fee": fee, "amount": amount, - "change": change_amount if change_amount > 546 else 0, + "change": change_amount, "total_input": total_input, "recipient": recipient, + "fee_rate_used": fee_rate, + "vsize": estimated_vsize, } @@ -397,22 +441,6 @@ def decrypt_mnemonic( return AESCipher(key=k).decrypt(m, urlsafe=urlsafe) -async def encrypt_secret(value: str) -> str: - server_secret = await get_or_create_server_secret() - key_bytes = hashlib.sha256(server_secret.encode()).digest() - fernet_key = base64.urlsafe_b64encode(key_bytes) - f = Fernet(fernet_key) - return f.encrypt(value.encode()).decode() - - -async def decrypt_secret(encrypted: str) -> str: - server_secret = await get_or_create_server_secret() - key_bytes = hashlib.sha256(server_secret.encode()).digest() - fernet_key = base64.urlsafe_b64encode(key_bytes) - f = Fernet(fernet_key) - return f.decrypt(encrypted.encode()).decode() - - def sha256(data: bytes) -> bytes: return hashlib.sha256(data).digest() @@ -432,7 +460,7 @@ def taproot_sighash( ) -> bytes: """ Compute BIP341 taproot key-path sighash manually. - """ + """ # sha_prevouts prevouts = b"" @@ -496,11 +524,9 @@ def taproot_sighash( ) return tagged_hash("TapSighash", preimage) + def generate_labeled_sp_address( - scan_secret_hex: str, - spend_pub_hex: str, - m: int, - hrp: str = 'sp' + scan_secret_hex: str, spend_pub_hex: str, m: int, hrp: str = "sp" ) -> str: """ Derive a BIP352 labeled Silent Payment address. @@ -517,22 +543,20 @@ def generate_labeled_sp_address( ).digest() # B_m = B_spend + label_hash * G - B_m = coincurve.PublicKey.combine_keys([ - coincurve.PublicKey(spend_pub_bytes), - coincurve.PublicKey.from_secret(label_hash), - ]).format(compressed=True) + B_m = coincurve.PublicKey.combine_keys( + [ + coincurve.PublicKey(spend_pub_bytes), + coincurve.PublicKey.from_secret(label_hash), + ] + ).format(compressed=True) # B_scan pubkey B_scan = coincurve.PublicKey.from_secret(scan_secret_bytes).format(compressed=True) - return bech32_encode( - hrp, - [0] + convertbits(B_scan + B_m, 8, 5), - Encoding.BECH32M - ) + return bech32_encode(hrp, [0] + convertbits(B_scan + B_m, 8, 5), Encoding.BECH32M) def get_spend_pub_from_secret(spend_secret_hex: str) -> str: - """Derive compressed spend public key from spend private key hex.""" + """Derive compressed spend public key from spend private key hex.""" pub = coincurve.PublicKey.from_secret(bytes.fromhex(spend_secret_hex)) - return pub.format(compressed=True).hex() \ No newline at end of file + return pub.format(compressed=True).hex() diff --git a/migrations.py b/migrations.py index dc13d86..e65d24c 100644 --- a/migrations.py +++ b/migrations.py @@ -51,6 +51,7 @@ async def m001_initial(db): """ ) + async def m002_subaccounts(db): await db.execute(""" CREATE TABLE IF NOT EXISTS silnt.wallet_addresses ( @@ -60,4 +61,4 @@ async def m002_subaccounts(db): label_index INTEGER NOT NULL, created_at INTEGER NOT NULL DEFAULT 0 ) - """) \ No newline at end of file + """) diff --git a/models.py b/models.py index 0eb320c..87f0cb3 100644 --- a/models.py +++ b/models.py @@ -6,7 +6,7 @@ class BlindbitConfig(BaseModel): blindbit_url: str = "" - mempool_url: str = "https://mempool.space" + mempool_url: str = "https://mempool.space" class CreateWallet(BaseModel): @@ -53,7 +53,7 @@ class BuildTxRequest(BaseModel): wallet_id: str recipient: str amount: int - fee_rate: int = 1 + fee_rate: float = 1 memo: str = "" utxos: list[dict] = [] # each: {txid, amount, vout} @@ -64,10 +64,11 @@ class BroadcastTxRequest(BaseModel): spent_txids: list[str] = [] -class Config(BaseModel): +class Config(BaseModel): sats_denominated: bool = True network: str = "mainnet" + class WalletAddress(BaseModel): id: str wallet_id: str @@ -75,9 +76,11 @@ class WalletAddress(BaseModel): label_index: int created_at: int = 0 + class PreviewAddressRequest(BaseModel): label_index: int + class SaveAddressRequest(BaseModel): sp_address: str - label_index: int \ No newline at end of file + label_index: int diff --git a/static/js/index.js b/static/js/index.js index 2b1d7fb..8e39368 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -32,6 +32,8 @@ window.app = Vue.createApp({ }, showBroadcastConfirm: false, sendTxFee: 0, + sendTxAmount: 0, + sendTxVsize: 0, ...tables, ...tableData, walletAccounts: [], @@ -44,13 +46,13 @@ window.app = Vue.createApp({ sendForm: { recipient: '', amount: 0, - feeRate: 1, + feeRate: 1.0, memo: '', useAllUtxos: false }, sendLoading: false, broadcastLoading: false, - sendTxResult: null + sendTxResult: null } }, computed: { @@ -310,6 +312,8 @@ window.app = Vue.createApp({ openSendDialog: function (wallet) { this.sendWallet = wallet this.sendTxResult = null + this.sendTxAmount = 0 + this.sendTxVsize = 0 this.sendForm = { recipient: '', amount: 0, @@ -346,7 +350,7 @@ window.app = Vue.createApp({ wallet_id: this.sendWallet.id, recipient: this.sendForm.recipient, amount: this.sendForm.useAllUtxos ? this.sendSelectedTotal : this.sendForm.amount, - fee_rate: this.sendForm.feeRate, + fee_rate: Math.max(0.1, parseFloat(this.sendForm.feeRate)) || 0.1, memo: this.sendForm.memo, utxos: selectedUtxos.map(u => ({ txid: u.txid, @@ -359,7 +363,9 @@ window.app = Vue.createApp({ } ) this.sendTxResult = data.psbt || data.tx_hex || JSON.stringify(data) - this.sendTxFee = data.fee + this.sendTxFee = data.fee + this.sendTxAmount = data.amount // ← store actual amount from backend + this.sendTxVsize = data.vsize // ← store vsize for display this.$q.notify({ type: 'positive', message: 'Transaction built successfully.', diff --git a/templates/silnt/index.html b/templates/silnt/index.html index 82db1a5..c203ebd 100644 --- a/templates/silnt/index.html +++ b/templates/silnt/index.html @@ -196,6 +196,9 @@
Send Payment
v-model.number="sendForm.feeRate" type="number" label="Fee Rate (sat/vB)" + min="0.1" + step="0.1" + hint="Minimum 0.1 sat/vB" class="q-mb-md" > @@ -393,18 +396,23 @@
Resolved Address
- -
Confirm Broadcast
+ +
+
Confirm Broadcast
+ + +
-

- You are about to broadcast this transaction to the Bitcoin network. - This action cannot be undone. -

-
Amount
-
+
+
+ Adjusted from sats to avoid dust change. +
@@ -418,6 +426,10 @@
Confirm Broadcast
Fee
+
@@ -428,12 +440,7 @@
Confirm Broadcast
:loading="broadcastLoading" @click="broadcastTransaction" > - Cancel + Cancel
diff --git a/views_api.py b/views_api.py index c8591d4..f26a63f 100644 --- a/views_api.py +++ b/views_api.py @@ -6,11 +6,11 @@ from .helpers.wallet import ( generate_silent_wallet_address, decrypt_mnemonic, - decrypt_spend_key, - decrypt_secret, + encrypt_for_wallet, + decrypt_for_wallet, build_transaction, generate_labeled_sp_address, - get_spend_pub_from_secret + get_spend_pub_from_secret, ) from .helpers.scan import scan_wallet, get_scan_progress, request_scan_stop from .helpers.address_resolver import bip353_resolve @@ -40,8 +40,9 @@ update_unconfirmed_utxo, get_wallet_addresses, count_wallet_addresses, - insert_wallet_address, - delete_wallet_address + insert_wallet_address, + delete_wallet_label_address, + delete_wallet_label_addresses, ) from .models import ( @@ -50,19 +51,17 @@ WalletAccount, BuildTxRequest, BroadcastTxRequest, - Config, + Config, ScanWalletRequest, SaveAddressRequest, - PreviewAddressRequest + PreviewAddressRequest, ) - MAX_ADDRESSES_PER_WALLET = 10 silnt_api_router = APIRouter() - # ── Wallets ────────────────────────────────────────────────────────────────── @@ -91,8 +90,9 @@ async def api_wallet_create( data: CreateWallet, key_info: WalletTypeInfo = Depends(require_invoice_key) ) -> str: try: + wallet_id = urlsafe_short_hash() new_wallet = WalletAccount( - id=urlsafe_short_hash(), + id=wallet_id, user=key_info.wallet.user, title=data.title, balance=0, @@ -103,10 +103,14 @@ async def api_wallet_create( spend_key="", scan_secret="", ) - (sp_address, scan_secret, spend_key) = await generate_silent_wallet_address( + ( + sp_address, + scan_secret_hex, + spend_key_hex, + ) = await generate_silent_wallet_address( decrypt_mnemonic(data.mnemonic, str(data.last_height)) ) - if not all([sp_address, scan_secret, spend_key]): + if not all([sp_address, scan_secret_hex, spend_key_hex]): raise ValueError( f"Wallet '{data.title}' cannot be created with given mnemonic!" ) @@ -142,8 +146,11 @@ async def api_wallet_create( status_code=HTTPStatus.BAD_REQUEST, detail=f"BIP353 resolution failed for {data.hr_address}: {str(e)}", ) - new_wallet.scan_secret = scan_secret - new_wallet.spend_key = spend_key + adminkey = key_info.wallet.adminkey + new_wallet.scan_secret = encrypt_for_wallet( + scan_secret_hex, adminkey, wallet_id + ) + new_wallet.spend_key = encrypt_for_wallet(spend_key_hex, adminkey, wallet_id) new_wallet.sp_address = sp_address await create_silnt_wallet(new_wallet) except Exception as exc: @@ -166,13 +173,11 @@ async def api_wallet_update( status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." ) if data.hr_address is not None and data.hr_address != wallet.hr_address: - # Validate BIP353 resolves to this wallet's SP address + # Validate BIP353 resolves to this wallet's SP address try: resolved = bip353_resolve(data.hr_address) result = resolved.get("result", "") - result = ( - result.replace("bitcoin:?sp=", "").replace("sp=", "").strip() - ) + result = result.replace("bitcoin:?sp=", "").replace("sp=", "").strip() if result.lower() != wallet.sp_address.lower(): raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, @@ -210,18 +215,19 @@ async def api_wallet_delete(wallet_id: str): ) await delete_silnt_wallet(wallet_id) await delete_utxos_for_wallet(wallet_id) - await delete_wallet_addresses(wallet_id) + await delete_wallet_label_addresses(wallet_id) return "", HTTPStatus.NO_CONTENT @silnt_api_router.get("/api/v1/wallet/{wallet_id}/addresses") async def api_get_wallet_addresses( - wallet_id: str, - key_info: WalletTypeInfo = Depends(require_invoice_key) + wallet_id: str, key_info: WalletTypeInfo = Depends(require_invoice_key) ): wallet = await get_silnt_wallet(wallet_id) if not wallet: - raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." + ) if wallet.user != key_info.wallet.user: raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") addresses = await get_wallet_addresses(wallet_id) @@ -232,51 +238,55 @@ async def api_get_wallet_addresses( async def api_preview_wallet_address( wallet_id: str, data: PreviewAddressRequest, - key_info: WalletTypeInfo = Depends(require_invoice_key) + key_info: WalletTypeInfo = Depends(require_invoice_key), ): wallet = await get_silnt_wallet(wallet_id) if not wallet: - raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." + ) if wallet.user != key_info.wallet.user: raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") - scan_secret = await decrypt_secret(wallet.scan_secret) - spend_key_encrypted = await get_spend_key(wallet_id) - spend_key_hex = decrypt_spend_key(spend_key_encrypted, scan_secret) + adminkey = key_info.wallet.adminkey + scan_secret = decrypt_for_wallet(wallet.scan_secret, adminkey, wallet_id) + spend_key_hex = decrypt_for_wallet(wallet.spend_key, adminkey, wallet_id) spend_pub_hex = get_spend_pub_from_secret(spend_key_hex) - hrp = 'sp' try: sp_address = generate_labeled_sp_address( scan_secret_hex=scan_secret, spend_pub_hex=spend_pub_hex, m=data.label_index, - hrp=hrp + hrp="sp", ) except Exception as e: raise HTTPException( status_code=HTTPStatus.INTERNAL_SERVER_ERROR, - detail=f"Failed to generate address: {str(e)}" + detail=f"Failed to generate address: {str(e)}", ) return { "sp_address": sp_address, "label_index": data.label_index, - "wallet_id": wallet_id + "wallet_id": wallet_id, } + @silnt_api_router.delete("/api/v1/wallet/{wallet_id}/addresses/{address_id}") async def api_delete_wallet_address( wallet_id: str, address_id: str, - key_info: WalletTypeInfo = Depends(require_invoice_key) + key_info: WalletTypeInfo = Depends(require_invoice_key), ): wallet = await get_silnt_wallet(wallet_id) if not wallet: - raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." + ) if wallet.user != key_info.wallet.user: raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") - await delete_wallet_address(address_id, wallet_id) + await delete_wallet_label_address(address_id, wallet_id) return "", HTTPStatus.NO_CONTENT @@ -284,11 +294,13 @@ async def api_delete_wallet_address( async def api_save_generated_wallet_address( wallet_id: str, data: SaveAddressRequest, - key_info: WalletTypeInfo = Depends(require_invoice_key) + key_info: WalletTypeInfo = Depends(require_invoice_key), ): wallet = await get_silnt_wallet(wallet_id) if not wallet: - raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." + ) if wallet.user != key_info.wallet.user: raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") @@ -296,7 +308,7 @@ async def api_save_generated_wallet_address( if count >= MAX_ADDRESSES_PER_WALLET: raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, - detail=f"Maximum of {MAX_ADDRESSES_PER_WALLET} addresses per wallet reached." + detail=f"Maximum of {MAX_ADDRESSES_PER_WALLET} addresses per wallet reached.", ) addr_id = urlsafe_short_hash() await insert_wallet_address(wallet_id, data.sp_address, data.label_index, addr_id) @@ -304,9 +316,10 @@ async def api_save_generated_wallet_address( "sp_address": data.sp_address, "label_index": data.label_index, "wallet_id": wallet_id, - "id": addr_id + "id": addr_id, } + @silnt_api_router.get( "/api/v1/oracle/tip", dependencies=[Depends(require_invoice_key)], @@ -392,6 +405,7 @@ async def api_scan_wallet( try: result = await scan_wallet( wallet_id=wallet_id, + adminkey=key_info.wallet.adminkey, from_height=data.from_height, to_height=data.to_height, ) @@ -432,48 +446,42 @@ async def api_resolve_bip353( # Transactions @silnt_api_router.post("/api/v1/tx/build", dependencies=[Depends(require_admin_key)]) -async def api_build_transaction(data: BuildTxRequest): +async def api_build_transaction( + data: BuildTxRequest, key_info: WalletTypeInfo = Depends(require_admin_key) +): try: - # ── Load wallet ─────────────────────────────────────────────── wallet = await get_silnt_wallet(data.wallet_id) if not wallet: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." ) - - # ── Decrypt keys ────────────────────────────────────────────── - spend_key_encrypted = await get_spend_key(data.wallet_id) - if not spend_key_encrypted: + if wallet.user != key_info.wallet.user: raise HTTPException( - status_code=HTTPStatus.BAD_REQUEST, - detail="No spend key found for this wallet.", + status_code=HTTPStatus.FORBIDDEN, detail="Access denied." ) - scan_secret = await decrypt_secret(wallet.scan_secret) - if not scan_secret: - raise HTTPException( - status_code=HTTPStatus.BAD_REQUEST, - detail="Failed to decrypt scan secret.", - ) + adminkey = key_info.wallet.adminkey + scan_secret = decrypt_for_wallet(wallet.scan_secret, adminkey, data.wallet_id) + spend_key_hex = decrypt_for_wallet(wallet.spend_key, adminkey, data.wallet_id) - spend_key_hex = decrypt_spend_key(spend_key_encrypted, scan_secret) - if not spend_key_hex: + if not scan_secret or not spend_key_hex: raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, - detail="Failed to decrypt spend key.", + detail="Failed to decrypt wallet keys.", ) + if "@" in data.recipient: user, domain = data.recipient.strip().split("@") - if user is not None and domain is not None: + if user and domain: resolved = bip353_resolve(data.recipient) result = resolved["result"].replace("bitcoin:?sp=", "") if not result.startswith("sp1"): raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, - detail="Address must resolve to SilenPayment address (sp1).", + detail="Address must resolve to Silent Payment address (sp1).", ) data.recipient = result - # ── Build transaction ───────────────────────────────────────── + result = build_transaction( spend_key_hex=spend_key_hex, recipient=data.recipient, @@ -483,7 +491,6 @@ async def api_build_transaction(data: BuildTxRequest): network=wallet.network, ) return result - except HTTPException: raise except Exception as exc: @@ -497,11 +504,11 @@ async def api_build_transaction(data: BuildTxRequest): @silnt_api_router.post( "/api/v1/tx/broadcast", dependencies=[Depends(require_admin_key)] ) -async def api_broadcast_transaction(data: BroadcastTxRequest): +async def api_broadcast_transaction(data: BroadcastTxRequest): try: blindbit = await get_blindbit_config() config = Config() - base = (blindbit.mempool_url or "https://mempool.space" ).rstrip("/") + base = (blindbit.mempool_url or "https://mempool.space").rstrip("/") mempool_url = f"{base}/api/tx" async with httpx.AsyncClient(timeout=30.0) as client: @@ -515,9 +522,11 @@ async def api_broadcast_transaction(data: BroadcastTxRequest): ) txid = resp.text.strip() if data.spent_txids and data.wallet_id: - for spent_txid in data.spent_txids: - await update_unconfirmed_utxo(data.wallet_id, spent_txid) - logger.info(f"Marked {len(data.spent_txids)} UTXOs as unconfirmed_spent after broadcast of {txid}") + for spent_txid in data.spent_txids: + await update_unconfirmed_utxo(data.wallet_id, spent_txid) + logger.info( + f"Marked {len(data.spent_txids)} UTXOs as unconfirmed_spent after broadcast of {txid}" + ) return {"txid": txid} except HTTPException: @@ -540,7 +549,7 @@ async def api_get_config( blindbit = await get_blindbit_config() config = Config() return { - "mempool_endpoint": blindbit.mempool_url or "https://mempool.space", + "mempool_endpoint": blindbit.mempool_url or "https://mempool.space", "sats_denominated": config.sats_denominated, "network": config.network, } From 25311af0909e9ce4671cf690a77e444f84cff586 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Sun, 3 May 2026 23:32:13 +0100 Subject: [PATCH 51/83] rem bb config rec --- crud.py | 1 - 1 file changed, 1 deletion(-) diff --git a/crud.py b/crud.py index f61258f..dbb241a 100644 --- a/crud.py +++ b/crud.py @@ -15,7 +15,6 @@ # Singleton row ID for the global blindbit config BLINDBIT_CONFIG_ID = "blindbit" -SILNT_SECRET_ID = "silnt_to_rule_them_all" async def create_silnt_wallet(wallet: WalletAccount) -> WalletAccount: From 39060cb07b40b5e526e3187c20e6d38fc637207e Mon Sep 17 00:00:00 2001 From: Ponthief Date: Thu, 7 May 2026 08:09:48 +0100 Subject: [PATCH 52/83] fix incorrect balance and DNS resolve --- helpers/address_resolver.py | 111 ++++++++++++++++++++++++++++--- static/components/wallet-list.js | 39 ++++++----- 2 files changed, 121 insertions(+), 29 deletions(-) diff --git a/helpers/address_resolver.py b/helpers/address_resolver.py index 70dd427..c774dc8 100644 --- a/helpers/address_resolver.py +++ b/helpers/address_resolver.py @@ -1,9 +1,70 @@ import dns.resolver +import dns.message +import dns.query +import dns.name +import dns.rdatatype +import dns.flags from http import HTTPStatus from fastapi import HTTPException +from loguru import logger +# DNSSEC-validating resolvers — both validate the full chain and set AD flag +DNSSEC_RESOLVERS = ['1.1.1.1', '8.8.8.8', '9.9.9.9'] -def bip353_resolve(address: str): +# Authentic Data flag (RFC 4035) — set by resolver when DNSSEC validation passed +AD_FLAG = 0x0020 + + +def _query_txt_with_dnssec(qname: str) -> tuple[list[str], bool]: + """ + Query a TXT record using a DNSSEC-validating resolver. + Returns (txt_records, dnssec_validated). + dnssec_validated is True only when the AD flag is set in the response, + meaning the upstream resolver successfully validated the DNSSEC chain. + Tries each resolver in DNSSEC_RESOLVERS in order. + """ + qname_obj = dns.name.from_text(qname) + + # Build query with DO (DNSSEC OK) bit set so resolver includes RRSIGs + request = dns.message.make_query(qname_obj, dns.rdatatype.TXT, want_dnssec=True) + + last_error = None + for nameserver in DNSSEC_RESOLVERS: + try: + # Try TCP first (more reliable for DNSSEC responses which can be large) + try: + response = dns.query.tcp(request, nameserver, timeout=10) + except Exception: + response = dns.query.udp(request, nameserver, timeout=10) + + # AD flag set = resolver validated the full DNSSEC chain + dnssec_valid = bool(response.flags & AD_FLAG) + + # Extract TXT records from answer section + records = [] + for rrset in response.answer: + if rrset.rdtype == dns.rdatatype.TXT: + for rdata in rrset: + records.append("".join(s.decode() for s in rdata.strings)) + + if records: + return records, dnssec_valid + + # Check for NXDOMAIN (RCODE 3) + if response.rcode() == dns.rcode.NXDOMAIN: + raise dns.resolver.NXDOMAIN() + + except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): + raise + except Exception as e: + last_error = e + logger.warning(f"DNSSEC query to {nameserver} failed: {e}, trying next") + continue + + raise Exception(f"All DNSSEC resolvers failed. Last error: {last_error}") + + +def bip353_resolve(address: str) -> dict: try: user, domain = address.strip().split("@") except ValueError: @@ -11,22 +72,50 @@ def bip353_resolve(address: str): status_code=HTTPStatus.BAD_REQUEST, detail="Invalid BIP353 address format. Expected user@domain.com", ) + + dns_domain = f"{user}.user._bitcoin-payment.{domain}" + try: - dns_domain = f"{user}.user._bitcoin-payment.{domain}" - answers = dns.resolver.resolve(dns_domain, "TXT") - result = "" - for rdata in answers: - result = "".join([a.decode() for a in rdata.strings]) - break - if not result: + records, dnssec_valid = _query_txt_with_dnssec(dns_domain) + + if not records: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, detail=f"No TXT record found for {dns_domain}", ) - return {"address": address, "dns_domain": dns_domain, "result": result} + + if not dnssec_valid: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=( + f"DNSSEC validation failed for {dns_domain}. " + "The domain must have valid DNSSEC signatures. " + "Resolving this address would be unsafe." + ), + ) + + result = records[0] + + if not result.startswith("bitcoin:"): + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=f"TXT record does not contain a valid bitcoin: URI: {result}", + ) + + logger.info(f"BIP353 resolved {address} → {result} (DNSSEC validated)") + return { + "address": address, + "dns_domain": dns_domain, + "result": result, + "dnssec": True, + } + + except HTTPException: + raise except dns.resolver.NXDOMAIN: raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail=f"Domain not found for {address}" + status_code=HTTPStatus.NOT_FOUND, + detail=f"Domain not found: {dns_domain}", ) except dns.resolver.NoAnswer: raise HTTPException( @@ -37,4 +126,4 @@ def bip353_resolve(address: str): raise HTTPException( status_code=HTTPStatus.BAD_GATEWAY, detail=f"DNS resolution failed: {str(exc)}", - ) + ) \ No newline at end of file diff --git a/static/components/wallet-list.js b/static/components/wallet-list.js index 6271c47..8b8d944 100644 --- a/static/components/wallet-list.js +++ b/static/components/wallet-list.js @@ -80,27 +80,30 @@ window.app.component('wallet-list', { } }, watch: { - scannedUtxos: { - deep: true, - handler(result) { - if (!result || !result.utxos || !result.utxos.length) return + scannedUtxos: { + deep: true, + handler(result) { + if (!result || !result.utxos || !result.utxos.length) return - const newBalance = result.utxos - .filter(u => u.utxo_state === 'unspent') - .reduce((sum, u) => sum + (u.amount || 0), 0) - this.walletAccounts.forEach(async wallet => { - // Only update if balance actually changed - if (newBalance === wallet.balance) return + // Get wallet_id from the UTXOs themselves + const walletId = result.utxos[0]?.wallet_id + if (!walletId) return - // Update backend first - await this.updateWalletBalance(wallet.id, newBalance) + // Only update the specific wallet — not all wallets + const wallet = this.walletAccounts.find(w => w.id === walletId) + if (!wallet) return - // Then update local state reactively - wallet.balance = newBalance - }) - } - } -}, + const newBalance = result.utxos + .filter(u => u.utxo_state === 'unspent') + .reduce((sum, u) => sum + (u.amount || 0), 0) + + if (newBalance === wallet.balance) return + + this.updateWalletBalance(wallet.id, newBalance) + wallet.balance = newBalance + } + } + }, methods: { satBtc(val, showUnit = true) { return satOrBtc(val, showUnit, this.satsDenominated) From 347533a2a311095f1093ae26bb8c969d35a2b774 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Fri, 8 May 2026 12:18:14 +0100 Subject: [PATCH 53/83] drop storing keys in the db --- crud.py | 23 ++--- helpers/scan.py | 8 +- helpers/wallet.py | 93 +++++++-------------- migrations.py | 4 +- models.py | 12 +-- static/components/wallet-list.js | 11 ++- templates/silnt/components/wallet-list.html | 20 +++-- views_api.py | 70 +++++++--------- 8 files changed, 99 insertions(+), 142 deletions(-) diff --git a/crud.py b/crud.py index dbb241a..678bf7a 100644 --- a/crud.py +++ b/crud.py @@ -30,13 +30,16 @@ async def get_silnt_wallet(wallet_id: str) -> Optional[WalletAccount]: ) -async def get_silnt_wallets(user: str, network: str) -> list[WalletAccount]: +async def get_silnt_wallets(user: str, network: Optional[str] = None) -> list[WalletAccount]: + if network: + return await db.fetchall( + 'SELECT * FROM silnt.wallets WHERE "user" = :user AND network = :network ORDER BY network, title', + {"user": user, "network": network}, + WalletAccount, + ) return await db.fetchall( - """ - SELECT * FROM silnt.wallets - WHERE "user" = :user AND network = :network - """, - {"user": user, "network": network}, + 'SELECT * FROM silnt.wallets WHERE "user" = :user ORDER BY network, title', + {"user": user}, WalletAccount, ) @@ -125,14 +128,6 @@ async def update_title(wallet_id: str, title: str) -> Optional[WalletAccount]: ) -async def get_spend_key(wallet_id: str) -> Optional[str]: - row = await db.fetchone( - "SELECT spend_key FROM silnt.wallets WHERE id = :id", - {"id": wallet_id}, - ) - return row["spend_key"] if row else None - - async def get_utxos_for_wallet(wallet_id: str) -> list[UTXORecord]: return await db.fetchall( "SELECT * FROM silnt.utxos WHERE wallet_id = :wallet_id ORDER BY timestamp DESC", diff --git a/helpers/scan.py b/helpers/scan.py index da2349c..5094c9d 100644 --- a/helpers/scan.py +++ b/helpers/scan.py @@ -18,7 +18,6 @@ insert_utxos_for_wallet, update_balance, ) -from .wallet import decrypt_for_wallet _scan_progress: dict[str, dict] = {} _scan_stop: dict[str, bool] = {} @@ -508,7 +507,8 @@ def set_scan_progress(wallet_id, current, total, found, active=True): async def scan_wallet( wallet_id: str, - adminkey: str, + scan_secret_hex: str, # passed from client, never stored + spend_secret_hex: str, from_height: Optional[int] = None, to_height: Optional[int] = None, ) -> dict: @@ -518,9 +518,7 @@ async def scan_wallet( blindbit = await get_blindbit_config() if not blindbit.blindbit_url: raise ValueError("BlindBit Oracle URL not configured") - - scan_secret_hex = decrypt_for_wallet(wallet.scan_secret, adminkey, wallet_id) - spend_secret_hex = decrypt_for_wallet(wallet.spend_key, adminkey, wallet_id) + scan_secret_bytes = bytes.fromhex(scan_secret_hex) spend_secret_bytes = bytes.fromhex(spend_secret_hex) spend_pub_bytes = coincurve.PublicKey.from_secret(spend_secret_bytes).format( diff --git a/helpers/wallet.py b/helpers/wallet.py index 0948582..289d36b 100644 --- a/helpers/wallet.py +++ b/helpers/wallet.py @@ -2,7 +2,6 @@ import coincurve import hashlib import httpx -import hmac import io import math import struct @@ -13,8 +12,6 @@ from .curve import bech32_encode, Encoding from .curve import pubkey_point_gen_from_int, int_from_bytes, Point from loguru import logger - -# from ..crud import get_or_create_server_secret from lnbits.utils.crypto import AESCipher from cryptography.fernet import Fernet from embit.transaction import ( @@ -43,44 +40,6 @@ from embit.ec import SchnorrSig -# ── New adminkey-based encryption (add after existing Fernet imports) ───────── - - -def derive_wallet_key(adminkey: str, wallet_id: str) -> bytes: - """Derive a per-wallet 32-byte key from adminkey + wallet_id via HMAC-SHA256. - Never stored — must be re-derived on every use from the caller's adminkey.""" - return hmac.new( - adminkey.encode(), msg=wallet_id.encode(), digestmod=hashlib.sha256 - ).digest() - - -def encrypt_for_wallet(plaintext: str, adminkey: str, wallet_id: str) -> str: - """Fernet-encrypt a string using a key derived from adminkey + wallet_id.""" - key = base64.urlsafe_b64encode(derive_wallet_key(adminkey, wallet_id)) - return Fernet(key).encrypt(plaintext.encode()).decode() - - -def decrypt_for_wallet(encrypted: str, adminkey: str, wallet_id: str) -> str: - """Fernet-decrypt a value produced by encrypt_for_wallet.""" - key = base64.urlsafe_b64encode(derive_wallet_key(adminkey, wallet_id)) - return Fernet(key).decrypt(encrypted.encode()).decode() - - -# def encrypt_spend_key(spend_priv_hex: str, scan_key_hex: str) -> str: -# # Derive a 32-byte Fernet key from scan_key_hex -# key_bytes = hashlib.sha256(scan_key_hex.encode()).digest() -# fernet_key = base64.urlsafe_b64encode(key_bytes) -# f = Fernet(fernet_key) -# return f.encrypt(spend_priv_hex.encode()).decode() - - -# def decrypt_spend_key(encrypted: str, scan_key_hex: str) -> str: -# key_bytes = hashlib.sha256(scan_key_hex.encode()).digest() -# fernet_key = base64.urlsafe_b64encode(key_bytes) -# f = Fernet(fernet_key) -# return f.decrypt(encrypted.encode()).decode() - - def get_seed(mnemonic) -> bytes: """ Re‑creates the BIP‑39 seed from the hard‑coded mnemonic. @@ -90,20 +49,27 @@ def get_seed(mnemonic) -> bytes: return seed -def generate_hardened_keys(seed) -> dict: - root = bip32.HDKey.from_seed(seed, version=NETWORKS["main"]["xprv"]) - scan_private_key = root.derive("m/352h/0h/0h/1h/0").key.secret - spend_private_key = root.derive("m/352h/0h/0h/0h/0").key.secret - scank = root.derive("m/352h/0h/0h/1h/0").key.secret - spendk = root.derive("m/352h/0h/0h/0h/0") - # Store the keys in a dictionary - key_material = { - "scan_priv_key": scan_private_key, +def generate_hardened_keys(seed, network: str = 'mainnet') -> dict: + # BIP352: coin_type 0 = mainnet, 1 = testnet/signet + coin_type = 0 if network == 'mainnet' else 1 + xprv_version = NETWORKS["main"]["xprv"] if network == 'mainnet' else NETWORKS["test"]["xprv"] + + root = bip32.HDKey.from_seed(seed, version=xprv_version) + + scan_path = f"m/352h/{coin_type}h/0h/1h/0" + spend_path = f"m/352h/{coin_type}h/0h/0h/0" + + scan_private_key = root.derive(scan_path).key.secret + spend_private_key = root.derive(spend_path).key.secret + scank = root.derive(scan_path).key.secret + spendk = root.derive(spend_path) + + return { + "scan_priv_key": scan_private_key, "spend_priv_key": spend_private_key, - "scank": hexlify(scank).decode(), + "scank": hexlify(scank).decode(), "spendk": spendk.get_public_key(), } - return key_material def encode_silent_payment_address( @@ -119,19 +85,20 @@ def encode_silent_payment_address( return ret -async def generate_silent_wallet_address(mnemonic) -> tuple: +async def generate_silent_wallet_address(mnemonic, network: str = 'mainnet') -> tuple: seed = get_seed(mnemonic) - key_material = generate_hardened_keys(seed) - # Receiver's scan and spend public key - B_scan = pubkey_point_gen_from_int(int_from_bytes(key_material["scan_priv_key"])) + key_material = generate_hardened_keys(seed, network) + + B_scan = pubkey_point_gen_from_int(int_from_bytes(key_material["scan_priv_key"])) B_spend = pubkey_point_gen_from_int(int_from_bytes(key_material["spend_priv_key"])) - sp = encode_silent_payment_address(B_scan, B_spend, "sp", 0) - # Encrypt spend private key using scan key as encryption key + + # mainnet → 'sp', signet/testnet → 'tsp' + hrp = 'sp' if network == 'mainnet' else 'tsp' + sp = encode_silent_payment_address(B_scan, B_spend, hrp, 0) + spend_priv_hex = hexlify(key_material["spend_priv_key"]).decode() - scan_key_hex = key_material["scank"] - # encrypted_spend_key = encrypt_spend_key(spend_priv_hex, scan_key_hex) - # # Encrypt scan secret using server secret - # encrypted_scan_secret = await encrypt_secret(scan_key_hex) + scan_key_hex = key_material["scank"] + return (str(sp), scan_key_hex, spend_priv_hex) @@ -292,7 +259,7 @@ def build_transaction( input_scripts.append((actual_script, actual_x_only)) # ── 3. Recipient scriptpubkey ───────────────────────────────────── - if recipient.startswith("sp1"): + if recipient.startswith("sp1") or recipient.startswith("tsp1"): recipient_script = Script( derive_sp_scriptpubkey(recipient, spend_key.secret, utxos) ) diff --git a/migrations.py b/migrations.py index e65d24c..91d06c6 100644 --- a/migrations.py +++ b/migrations.py @@ -10,9 +10,7 @@ async def m001_initial(db): network TEXT DEFAULT 'mainnet', title TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT {db.timestamp_now}, - updated_at TIMESTAMPTZ NOT NULL DEFAULT {db.timestamp_now}, - scan_secret TEXT NOT NULL, - spend_key TEXT NOT NULL, + updated_at TIMESTAMPTZ NOT NULL DEFAULT {db.timestamp_now}, sp_address TEXT NOT NULL, hr_address TEXT NOT NULL, last_height INTEGER, diff --git a/models.py b/models.py index 87f0cb3..421d2e8 100644 --- a/models.py +++ b/models.py @@ -23,9 +23,7 @@ class WalletAccount(BaseModel): user: str title: str balance: int - network: str = "mainnet" - scan_secret: str - spend_key: str + network: str = "mainnet" sp_address: str hr_address: str last_height: int @@ -47,6 +45,8 @@ class UTXORecord(BaseModel): class ScanWalletRequest(BaseModel): from_height: Optional[int] = None to_height: Optional[int] = None + scan_secret: str + spend_key: str class BuildTxRequest(BaseModel): @@ -55,7 +55,8 @@ class BuildTxRequest(BaseModel): amount: int fee_rate: float = 1 memo: str = "" - utxos: list[dict] = [] # each: {txid, amount, vout} + utxos: list[dict] = [] + spend_key: str class BroadcastTxRequest(BaseModel): @@ -79,7 +80,8 @@ class WalletAddress(BaseModel): class PreviewAddressRequest(BaseModel): label_index: int - + scan_secret: str + spend_key: str class SaveAddressRequest(BaseModel): sp_address: str diff --git a/static/components/wallet-list.js b/static/components/wallet-list.js index 8b8d944..5808c65 100644 --- a/static/components/wallet-list.js +++ b/static/components/wallet-list.js @@ -21,7 +21,8 @@ window.app.component('wallet-list', { data: { title: '', hr_address: '', - last_height: '' + last_height: '', + network: 'mainnet' } }, updateDialog: { @@ -111,7 +112,7 @@ window.app.component('wallet-list', { addWalletAccount: async function () { this.showCreating = true const data = _.omit(this.formDialog.data, 'wallet') - data.network = this.network + data.network = this.formDialog.data.network || this.network // Validate BIP353 hr_address if provided if (data.hr_address && data.hr_address.trim() !== '') { const valid = await this.validateBip353(data.hr_address) @@ -407,7 +408,8 @@ window.app.component('wallet-list', { this.formDialog.data = { hr_address: '', // ← empty string not null last_height: '', - mnemonic: '', + mnemonic: '', + network: 'mainnet', is_unique: false } }, @@ -424,7 +426,8 @@ window.app.component('wallet-list', { this.formDialog.data = { hr_address: '', last_height: '', - mnemonic: '' + mnemonic: '', + network: 'mainnet' } this.formDialog.show = true }, diff --git a/templates/silnt/components/wallet-list.html b/templates/silnt/components/wallet-list.html index e1e6825..701cc05 100644 --- a/templates/silnt/components/wallet-list.html +++ b/templates/silnt/components/wallet-list.html @@ -69,13 +69,6 @@ class="row items-center no-wrap q-mt-xs" style="border-left: 2px solid #9c27b0; padding-left: 6px" > - unsaved @@ -293,6 +286,19 @@
Receive to Silent Payment Address
Email format - see BIP353 +
+
Network
+ +
list[WalletAccount]: return await get_silnt_wallets(key_info.wallet.user, network) @@ -102,13 +100,13 @@ async def api_wallet_create( sp_address="", spend_key="", scan_secret="", - ) + ) ( sp_address, scan_secret_hex, spend_key_hex, ) = await generate_silent_wallet_address( - decrypt_mnemonic(data.mnemonic, str(data.last_height)) + decrypt_mnemonic(data.mnemonic, str(data.last_height)), network=data.network ) if not all([sp_address, scan_secret_hex, spend_key_hex]): raise ValueError( @@ -116,18 +114,10 @@ async def api_wallet_create( ) wallets = await get_silnt_wallets(key_info.wallet.user, data.network) - existing_wallet = next( - ( - ew - for ew in wallets - if ew.sp_address == sp_address and ew.network == new_wallet.network - ), - None, - ) - if existing_wallet: + if any(w.sp_address == sp_address for w in wallets): raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, - detail=f"Silent Payment Wallet already exists!", + detail="Silent Payment Wallet already exists!", ) if data.hr_address: try: @@ -146,18 +136,23 @@ async def api_wallet_create( status_code=HTTPStatus.BAD_REQUEST, detail=f"BIP353 resolution failed for {data.hr_address}: {str(e)}", ) - adminkey = key_info.wallet.adminkey - new_wallet.scan_secret = encrypt_for_wallet( - scan_secret_hex, adminkey, wallet_id - ) - new_wallet.spend_key = encrypt_for_wallet(spend_key_hex, adminkey, wallet_id) + # adminkey = key_info.wallet.adminkey + # new_wallet.scan_secret = encrypt_for_wallet( + # scan_secret_hex, adminkey, wallet_id + # ) + # new_wallet.spend_key = encrypt_for_wallet(spend_key_hex, adminkey, wallet_id) new_wallet.sp_address = sp_address await create_silnt_wallet(new_wallet) except Exception as exc: raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, detail=str(exc) ) from exc - return "" + return { + "wallet_id": wallet_id, + "sp_address": sp_address, + "scan_secret": scan_secret_hex, # client must store this securely + "spend_key": spend_key_hex, # client must store this securely + } @silnt_api_router.put("/api/v1/wallet/{wallet_id}", status_code=HTTPStatus.OK) @@ -248,17 +243,15 @@ async def api_preview_wallet_address( if wallet.user != key_info.wallet.user: raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") - adminkey = key_info.wallet.adminkey - scan_secret = decrypt_for_wallet(wallet.scan_secret, adminkey, wallet_id) - spend_key_hex = decrypt_for_wallet(wallet.spend_key, adminkey, wallet_id) - spend_pub_hex = get_spend_pub_from_secret(spend_key_hex) + spend_pub_hex = get_spend_pub_from_secret(data.spend_key) + hrp = 'sp' if wallet.network == 'mainnet' else 'tsp' try: sp_address = generate_labeled_sp_address( - scan_secret_hex=scan_secret, + scan_secret_hex=data.scan_secret, spend_pub_hex=spend_pub_hex, m=data.label_index, - hrp="sp", + hrp = hrp ) except Exception as e: raise HTTPException( @@ -405,7 +398,8 @@ async def api_scan_wallet( try: result = await scan_wallet( wallet_id=wallet_id, - adminkey=key_info.wallet.adminkey, + scan_secret_hex=data.scan_secret, # from client request + spend_secret_hex=data.spend_key, from_height=data.from_height, to_height=data.to_height, ) @@ -460,15 +454,9 @@ async def api_build_transaction( status_code=HTTPStatus.FORBIDDEN, detail="Access denied." ) - adminkey = key_info.wallet.adminkey - scan_secret = decrypt_for_wallet(wallet.scan_secret, adminkey, data.wallet_id) - spend_key_hex = decrypt_for_wallet(wallet.spend_key, adminkey, data.wallet_id) - - if not scan_secret or not spend_key_hex: - raise HTTPException( - status_code=HTTPStatus.BAD_REQUEST, - detail="Failed to decrypt wallet keys.", - ) + if not data.spend_key: + raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, + detail="spend_key is required.") if "@" in data.recipient: user, domain = data.recipient.strip().split("@") @@ -483,7 +471,7 @@ async def api_build_transaction( data.recipient = result result = build_transaction( - spend_key_hex=spend_key_hex, + spend_key_hex=data.spend_key, recipient=data.recipient, amount=data.amount, fee_rate=data.fee_rate, From cf5d6a2db3591da6f1b6f316add2f1c9cb6648a1 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Tue, 19 May 2026 07:25:57 +0100 Subject: [PATCH 54/83] fix create_wallet --- views_api.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/views_api.py b/views_api.py index e36bb26..9248ea0 100644 --- a/views_api.py +++ b/views_api.py @@ -86,7 +86,7 @@ async def api_wallet_retrieve(wallet_id: str) -> WalletAccount: @silnt_api_router.post("/api/v1/wallet", status_code=HTTPStatus.OK) async def api_wallet_create( data: CreateWallet, key_info: WalletTypeInfo = Depends(require_invoice_key) -) -> str: +) -> dict: try: wallet_id = urlsafe_short_hash() new_wallet = WalletAccount( @@ -135,12 +135,7 @@ async def api_wallet_create( raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, detail=f"BIP353 resolution failed for {data.hr_address}: {str(e)}", - ) - # adminkey = key_info.wallet.adminkey - # new_wallet.scan_secret = encrypt_for_wallet( - # scan_secret_hex, adminkey, wallet_id - # ) - # new_wallet.spend_key = encrypt_for_wallet(spend_key_hex, adminkey, wallet_id) + ) new_wallet.sp_address = sp_address await create_silnt_wallet(new_wallet) except Exception as exc: @@ -160,7 +155,7 @@ async def api_wallet_update( wallet_id: str, data: CreateWallet, key_info: WalletTypeInfo = Depends(require_invoice_key), -) -> str: +) -> dict: try: wallet = await get_silnt_wallet(wallet_id) if not wallet: @@ -196,7 +191,7 @@ async def api_wallet_update( raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, detail=str(exc) ) from exc - return "" + return {} @silnt_api_router.delete( From 97c45185cbf0a6023fbd9adb054817a79271063c Mon Sep 17 00:00:00 2001 From: Ponthief Date: Wed, 20 May 2026 08:29:13 +0100 Subject: [PATCH 55/83] update bip353 address in Cloudflare --- crud.py | 43 ++++++++- helpers/address_resolver.py | 10 +- helpers/bip353_cloudflare.py | 148 ++++++++++++++++++++++++++++++ helpers/scan.py | 4 +- helpers/wallet.py | 26 +++--- models.py | 24 +++-- views_api.py | 171 ++++++++++++++++++++++++++++++++--- 7 files changed, 386 insertions(+), 40 deletions(-) create mode 100644 helpers/bip353_cloudflare.py diff --git a/crud.py b/crud.py index 678bf7a..b371f49 100644 --- a/crud.py +++ b/crud.py @@ -4,7 +4,14 @@ import secrets from lnbits.db import Database from lnbits.helpers import urlsafe_short_hash -from .models import Config, BlindbitConfig, WalletAccount, UTXORecord, WalletAddress +from .models import ( + Config, + BlindbitConfig, + WalletAccount, + UTXORecord, + WalletAddress, + CloudflareConfig, +) from embit.descriptor import Descriptor, Key from embit.descriptor.arguments import AllowedDerivation @@ -15,6 +22,7 @@ # Singleton row ID for the global blindbit config BLINDBIT_CONFIG_ID = "blindbit" +CF_CONFIG_ID = "cloudflare_config" async def create_silnt_wallet(wallet: WalletAccount) -> WalletAccount: @@ -30,7 +38,9 @@ async def get_silnt_wallet(wallet_id: str) -> Optional[WalletAccount]: ) -async def get_silnt_wallets(user: str, network: Optional[str] = None) -> list[WalletAccount]: +async def get_silnt_wallets( + user: str, network: Optional[str] = None +) -> list[WalletAccount]: if network: return await db.fetchall( 'SELECT * FROM silnt.wallets WHERE "user" = :user AND network = :network ORDER BY network, title', @@ -236,3 +246,32 @@ async def update_blindbit_config(config: BlindbitConfig) -> BlindbitConfig: {"id": BLINDBIT_CONFIG_ID, "json_data": json_data}, ) return config + + +async def get_cloudflare_config() -> CloudflareConfig: + row = await db.fetchone( + "SELECT json_data FROM silnt.blindbit_config WHERE id = :id", + {"id": CF_CONFIG_ID}, + ) + if not row: + return CloudflareConfig() + return CloudflareConfig(**json.loads(row["json_data"])) + + +async def update_cloudflare_config(config: CloudflareConfig) -> CloudflareConfig: + json_data = config.json() + existing = await db.fetchone( + "SELECT id FROM silnt.blindbit_config WHERE id = :id", + {"id": CF_CONFIG_ID}, + ) + if existing: + await db.execute( + "UPDATE silnt.blindbit_config SET json_data = :json_data WHERE id = :id", + {"json_data": json_data, "id": CF_CONFIG_ID}, + ) + else: + await db.execute( + "INSERT INTO silnt.blindbit_config (id, json_data) VALUES (:id, :json_data)", + {"id": CF_CONFIG_ID, "json_data": json_data}, + ) + return config diff --git a/helpers/address_resolver.py b/helpers/address_resolver.py index c774dc8..06f07b5 100644 --- a/helpers/address_resolver.py +++ b/helpers/address_resolver.py @@ -9,7 +9,7 @@ from loguru import logger # DNSSEC-validating resolvers — both validate the full chain and set AD flag -DNSSEC_RESOLVERS = ['1.1.1.1', '8.8.8.8', '9.9.9.9'] +DNSSEC_RESOLVERS = ["1.1.1.1", "8.8.8.8", "9.9.9.9"] # Authentic Data flag (RFC 4035) — set by resolver when DNSSEC validation passed AD_FLAG = 0x0020 @@ -104,10 +104,10 @@ def bip353_resolve(address: str) -> dict: logger.info(f"BIP353 resolved {address} → {result} (DNSSEC validated)") return { - "address": address, + "address": address, "dns_domain": dns_domain, - "result": result, - "dnssec": True, + "result": result, + "dnssec": True, } except HTTPException: @@ -126,4 +126,4 @@ def bip353_resolve(address: str) -> dict: raise HTTPException( status_code=HTTPStatus.BAD_GATEWAY, detail=f"DNS resolution failed: {str(exc)}", - ) \ No newline at end of file + ) diff --git a/helpers/bip353_cloudflare.py b/helpers/bip353_cloudflare.py new file mode 100644 index 0000000..ffa66e3 --- /dev/null +++ b/helpers/bip353_cloudflare.py @@ -0,0 +1,148 @@ +""" +BIP-353 DNS record management via Cloudflare API. +Creates/updates TXT records of the form: + {username}.user._bitcoin-payment.{domain} → "bitcoin:?sp={sp_address}" +""" + +import httpx +from loguru import logger + + +CF_API = "https://api.cloudflare.com/client/v4" + + +class CloudflareError(Exception): + pass + + +def _headers(api_token: str) -> dict: + return { + "Authorization": f"Bearer {api_token}", + "Content-Type": "application/json", + } + + +def bip353_record_name(username: str, domain: str) -> str: + """Full DNS name for a BIP-353 TXT record.""" + return f"{username}.user._bitcoin-payment.{domain}" + + +def bip353_record_content(sp_address: str) -> str: + """TXT record content per BIP-353 spec.""" + return f"bitcoin:?sp={sp_address}" + + +async def get_zone_domain(api_token: str, zone_id: str) -> str: + """Fetch the domain name for a Cloudflare zone.""" + async with httpx.AsyncClient(timeout=10.0) as client: + resp = await client.get( + f"{CF_API}/zones/{zone_id}", + headers=_headers(api_token), + ) + data = resp.json() + if not data.get("success"): + raise CloudflareError(f"Failed to fetch zone: {data.get('errors')}") + return data["result"]["name"] + + +async def find_existing_record( + api_token: str, zone_id: str, record_name: str +) -> str | None: + """Return the record ID if a TXT record already exists, else None.""" + async with httpx.AsyncClient(timeout=10.0) as client: + resp = await client.get( + f"{CF_API}/zones/{zone_id}/dns_records", + headers=_headers(api_token), + params={"type": "TXT", "name": record_name}, + ) + data = resp.json() + if not data.get("success"): + raise CloudflareError(f"Failed to query DNS records: {data.get('errors')}") + results = data.get("result", []) + return results[0]["id"] if results else None + + +async def create_bip353_record( + api_token: str, + zone_id: str, + username: str, + sp_address: str, + ttl: int = 300, +) -> dict: + """ + Create or update a BIP-353 TXT record in Cloudflare. + Returns {"record_name": ..., "hr_address": ..., "action": "created"|"updated"} + """ + domain = await get_zone_domain(api_token, zone_id) + record_name = bip353_record_name(username, domain) + content = bip353_record_content(sp_address) + + existing_id = await find_existing_record(api_token, zone_id, record_name) + + payload = { + "type": "TXT", + "name": record_name, + "content": content, + "ttl": ttl, + "comment": "BIP-353 Silent Payment address — managed by Thrilla", + } + + async with httpx.AsyncClient(timeout=10.0) as client: + if existing_id: + # Update existing record + resp = await client.put( + f"{CF_API}/zones/{zone_id}/dns_records/{existing_id}", + headers=_headers(api_token), + json=payload, + ) + action = "updated" + else: + # Create new record + resp = await client.post( + f"{CF_API}/zones/{zone_id}/dns_records", + headers=_headers(api_token), + json=payload, + ) + action = "created" + + data = resp.json() + if not data.get("success"): + errors = data.get("errors", []) + msg = errors[0].get("message", "Unknown error") if errors else "Unknown error" + raise CloudflareError(f"Cloudflare DNS {action} failed: {msg}") + + hr_address = f"{username}@{domain}" + logger.info(f"BIP-353 record {action}: {record_name} → {content}") + + return { + "record_name": record_name, + "hr_address": hr_address, + "domain": domain, + "action": action, + } + + +async def delete_bip353_record( + api_token: str, + zone_id: str, + username: str, +) -> bool: + """Delete a BIP-353 TXT record. Returns True if deleted, False if not found.""" + domain = await get_zone_domain(api_token, zone_id) + record_name = bip353_record_name(username, domain) + record_id = await find_existing_record(api_token, zone_id, record_name) + + if not record_id: + return False + + async with httpx.AsyncClient(timeout=10.0) as client: + resp = await client.delete( + f"{CF_API}/zones/{zone_id}/dns_records/{record_id}", + headers=_headers(api_token), + ) + data = resp.json() + if not data.get("success"): + raise CloudflareError(f"Failed to delete record: {data.get('errors')}") + + logger.info(f"BIP-353 record deleted: {record_name}") + return True diff --git a/helpers/scan.py b/helpers/scan.py index 5094c9d..7506341 100644 --- a/helpers/scan.py +++ b/helpers/scan.py @@ -507,7 +507,7 @@ def set_scan_progress(wallet_id, current, total, found, active=True): async def scan_wallet( wallet_id: str, - scan_secret_hex: str, # passed from client, never stored + scan_secret_hex: str, # passed from client, never stored spend_secret_hex: str, from_height: Optional[int] = None, to_height: Optional[int] = None, @@ -518,7 +518,7 @@ async def scan_wallet( blindbit = await get_blindbit_config() if not blindbit.blindbit_url: raise ValueError("BlindBit Oracle URL not configured") - + scan_secret_bytes = bytes.fromhex(scan_secret_hex) spend_secret_bytes = bytes.fromhex(spend_secret_hex) spend_pub_bytes = coincurve.PublicKey.from_secret(spend_secret_bytes).format( diff --git a/helpers/wallet.py b/helpers/wallet.py index 289d36b..3467ed1 100644 --- a/helpers/wallet.py +++ b/helpers/wallet.py @@ -49,25 +49,27 @@ def get_seed(mnemonic) -> bytes: return seed -def generate_hardened_keys(seed, network: str = 'mainnet') -> dict: +def generate_hardened_keys(seed, network: str = "mainnet") -> dict: # BIP352: coin_type 0 = mainnet, 1 = testnet/signet - coin_type = 0 if network == 'mainnet' else 1 - xprv_version = NETWORKS["main"]["xprv"] if network == 'mainnet' else NETWORKS["test"]["xprv"] + coin_type = 0 if network == "mainnet" else 1 + xprv_version = ( + NETWORKS["main"]["xprv"] if network == "mainnet" else NETWORKS["test"]["xprv"] + ) root = bip32.HDKey.from_seed(seed, version=xprv_version) - scan_path = f"m/352h/{coin_type}h/0h/1h/0" + scan_path = f"m/352h/{coin_type}h/0h/1h/0" spend_path = f"m/352h/{coin_type}h/0h/0h/0" - scan_private_key = root.derive(scan_path).key.secret + scan_private_key = root.derive(scan_path).key.secret spend_private_key = root.derive(spend_path).key.secret - scank = root.derive(scan_path).key.secret + scank = root.derive(scan_path).key.secret spendk = root.derive(spend_path) return { - "scan_priv_key": scan_private_key, + "scan_priv_key": scan_private_key, "spend_priv_key": spend_private_key, - "scank": hexlify(scank).decode(), + "scank": hexlify(scank).decode(), "spendk": spendk.get_public_key(), } @@ -85,19 +87,19 @@ def encode_silent_payment_address( return ret -async def generate_silent_wallet_address(mnemonic, network: str = 'mainnet') -> tuple: +async def generate_silent_wallet_address(mnemonic, network: str = "mainnet") -> tuple: seed = get_seed(mnemonic) key_material = generate_hardened_keys(seed, network) - B_scan = pubkey_point_gen_from_int(int_from_bytes(key_material["scan_priv_key"])) + B_scan = pubkey_point_gen_from_int(int_from_bytes(key_material["scan_priv_key"])) B_spend = pubkey_point_gen_from_int(int_from_bytes(key_material["spend_priv_key"])) # mainnet → 'sp', signet/testnet → 'tsp' - hrp = 'sp' if network == 'mainnet' else 'tsp' + hrp = "sp" if network == "mainnet" else "tsp" sp = encode_silent_payment_address(B_scan, B_spend, hrp, 0) spend_priv_hex = hexlify(key_material["spend_priv_key"]).decode() - scan_key_hex = key_material["scank"] + scan_key_hex = key_material["scank"] return (str(sp), scan_key_hex, spend_priv_hex) diff --git a/models.py b/models.py index 421d2e8..485679f 100644 --- a/models.py +++ b/models.py @@ -23,7 +23,7 @@ class WalletAccount(BaseModel): user: str title: str balance: int - network: str = "mainnet" + network: str = "mainnet" sp_address: str hr_address: str last_height: int @@ -45,8 +45,8 @@ class UTXORecord(BaseModel): class ScanWalletRequest(BaseModel): from_height: Optional[int] = None to_height: Optional[int] = None - scan_secret: str - spend_key: str + scan_secret: str + spend_key: str class BuildTxRequest(BaseModel): @@ -56,7 +56,7 @@ class BuildTxRequest(BaseModel): fee_rate: float = 1 memo: str = "" utxos: list[dict] = [] - spend_key: str + spend_key: str class BroadcastTxRequest(BaseModel): @@ -80,9 +80,21 @@ class WalletAddress(BaseModel): class PreviewAddressRequest(BaseModel): label_index: int - scan_secret: str - spend_key: str + scan_secret: str + spend_key: str + class SaveAddressRequest(BaseModel): sp_address: str label_index: int + + +class CloudflareConfig(BaseModel): + api_token: str = "" + zone_id: str = "" + domain: str = "" + + +class SetupBip353Request(BaseModel): + username: str # e.g. "alice" → alice@yourdomain.com + ttl: int = 300 # DNS TTL in seconds diff --git a/views_api.py b/views_api.py index 9248ea0..e985155 100644 --- a/views_api.py +++ b/views_api.py @@ -3,9 +3,10 @@ from base64 import b64encode import httpx import hashlib +import re from .helpers.wallet import ( generate_silent_wallet_address, - decrypt_mnemonic, + decrypt_mnemonic, build_transaction, generate_labeled_sp_address, get_spend_pub_from_secret, @@ -18,6 +19,12 @@ from lnbits.helpers import urlsafe_short_hash from loguru import logger from typing import Optional +from .helpers.bip353_cloudflare import ( + create_bip353_record, + get_zone_domain, + delete_bip353_record, + CloudflareError, +) from .crud import ( get_silnt_wallets, @@ -32,7 +39,7 @@ update_balance, get_silnt_wallet, get_blindbit_config, - update_blindbit_config, + update_blindbit_config, get_utxos_for_wallet, insert_utxos_for_wallet, update_unconfirmed_utxo, @@ -41,6 +48,8 @@ insert_wallet_address, delete_wallet_label_address, delete_wallet_label_addresses, + get_cloudflare_config, + update_cloudflare_config, ) from .models import ( @@ -53,6 +62,8 @@ ScanWalletRequest, SaveAddressRequest, PreviewAddressRequest, + CloudflareConfig, + SetupBip353Request, ) MAX_ADDRESSES_PER_WALLET = 10 @@ -100,7 +111,7 @@ async def api_wallet_create( sp_address="", spend_key="", scan_secret="", - ) + ) ( sp_address, scan_secret_hex, @@ -135,7 +146,7 @@ async def api_wallet_create( raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, detail=f"BIP353 resolution failed for {data.hr_address}: {str(e)}", - ) + ) new_wallet.sp_address = sp_address await create_silnt_wallet(new_wallet) except Exception as exc: @@ -143,10 +154,10 @@ async def api_wallet_create( status_code=HTTPStatus.BAD_REQUEST, detail=str(exc) ) from exc return { - "wallet_id": wallet_id, - "sp_address": sp_address, - "scan_secret": scan_secret_hex, # client must store this securely - "spend_key": spend_key_hex, # client must store this securely + "wallet_id": wallet_id, + "sp_address": sp_address, + "scan_secret": scan_secret_hex, # client must store this securely + "spend_key": spend_key_hex, # client must store this securely } @@ -239,14 +250,14 @@ async def api_preview_wallet_address( raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") spend_pub_hex = get_spend_pub_from_secret(data.spend_key) - hrp = 'sp' if wallet.network == 'mainnet' else 'tsp' + hrp = "sp" if wallet.network == "mainnet" else "tsp" try: sp_address = generate_labeled_sp_address( scan_secret_hex=data.scan_secret, spend_pub_hex=spend_pub_hex, m=data.label_index, - hrp = hrp + hrp=hrp, ) except Exception as e: raise HTTPException( @@ -393,7 +404,7 @@ async def api_scan_wallet( try: result = await scan_wallet( wallet_id=wallet_id, - scan_secret_hex=data.scan_secret, # from client request + scan_secret_hex=data.scan_secret, # from client request spend_secret_hex=data.spend_key, from_height=data.from_height, to_height=data.to_height, @@ -450,8 +461,9 @@ async def api_build_transaction( ) if not data.spend_key: - raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, - detail="spend_key is required.") + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, detail="spend_key is required." + ) if "@" in data.recipient: user, domain = data.recipient.strip().split("@") @@ -544,3 +556,136 @@ async def api_get_config( ) async def api_scan_progress(wallet_id: str): return get_scan_progress(wallet_id) + + +# ── GET Cloudflare config (admin only) ─────────────────────────────────────── +@silnt_api_router.get("/api/v1/cloudflare/config") +async def api_get_cloudflare_config( + key_info: WalletTypeInfo = Depends(require_admin_key), +) -> CloudflareConfig: + cf = await get_cloudflare_config() + # Backfill domain if credentials are present but domain is missing + # (e.g. config saved before the domain field existed) + if cf.api_token and cf.zone_id and not cf.domain: + try: + cf.domain = await get_zone_domain(cf.api_token, cf.zone_id) + await update_cloudflare_config(cf) + except Exception: + pass + return cf + + +# ── PUT Cloudflare config (admin only) ─────────────────────────────────────── +@silnt_api_router.put("/api/v1/cloudflare/config") +async def api_update_cloudflare_config( + data: CloudflareConfig, + key_info: WalletTypeInfo = Depends(require_admin_key), +) -> CloudflareConfig: + # Verify token + zone by fetching domain — also auto-populates data.domain + if data.api_token and data.zone_id: + try: + data.domain = await get_zone_domain(data.api_token, data.zone_id) + except Exception as e: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=f"Could not verify Cloudflare zone: {str(e)}", + ) + else: + data.domain = "" + return await update_cloudflare_config(data) + + +# ── POST setup BIP-353 for a wallet via Cloudflare ─────────────────────────── +@silnt_api_router.post("/api/v1/wallet/{wallet_id}/bip353/setup") +async def api_setup_bip353( + wallet_id: str, + data: SetupBip353Request, + key_info: WalletTypeInfo = Depends(require_invoice_key), +): + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." + ) + if wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + + # Reject if wallet already has BIP-353 — users must remove first, then create + if wallet.hr_address: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=f"Wallet already has BIP-353 address: {wallet.hr_address}. " + "Remove it first before creating a new one.", + ) + # Validate username format + if not re.match(r"^[a-zA-Z0-9._-]+$", data.username): + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail="Username must contain only letters, numbers, dots, hyphens, underscores.", + ) + + cf = await get_cloudflare_config() + if not cf.api_token or not cf.zone_id: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail="Cloudflare API not configured. Ask your administrator to set it up.", + ) + + try: + result = await create_bip353_record( + api_token=cf.api_token, + zone_id=cf.zone_id, + username=data.username.lower(), + sp_address=wallet.sp_address, + ttl=data.ttl, + ) + except CloudflareError as e: + raise HTTPException(status_code=HTTPStatus.BAD_GATEWAY, detail=str(e)) + except Exception as e: + raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)) + + # Update wallet hr_address + await update_hr_address(wallet_id, result["hr_address"]) + + return { + "hr_address": result["hr_address"], + "record_name": result["record_name"], + "action": result["action"], + "sp_address": wallet.sp_address, + } + + +# ── DELETE BIP-353 record for a wallet ─────────────────────────────────────── +@silnt_api_router.delete("/api/v1/wallet/{wallet_id}/bip353") +async def api_delete_bip353( + wallet_id: str, + key_info: WalletTypeInfo = Depends(require_invoice_key), +): + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." + ) + if wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + if not wallet.hr_address: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, detail="No BIP-353 address set." + ) + + cf = await get_cloudflare_config() + if not cf.api_token or not cf.zone_id: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, detail="Cloudflare API not configured." + ) + + try: + username = wallet.hr_address.split("@")[0] + deleted = await delete_bip353_record(cf.api_token, cf.zone_id, username) + except CloudflareError as e: + raise HTTPException(status_code=HTTPStatus.BAD_GATEWAY, detail=str(e)) + + # Clear hr_address from wallet + await update_hr_address(wallet_id, "") + + return {"deleted": deleted, "was": wallet.hr_address} From b0cf1c13567eb1d4bebd7d4460bbfa91a9e756af Mon Sep 17 00:00:00 2001 From: Ponthief Date: Fri, 22 May 2026 17:25:31 +0100 Subject: [PATCH 56/83] add option to recover the keys --- models.py | 4 ++++ views_api.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/models.py b/models.py index 485679f..096e7af 100644 --- a/models.py +++ b/models.py @@ -65,6 +65,10 @@ class BroadcastTxRequest(BaseModel): spent_txids: list[str] = [] +class RecoverKeysRequest(BaseModel): + mnemonic: str # encrypted (AES-encrypted with last_height as key) + last_height: int # encryption key + birth height + class Config(BaseModel): sats_denominated: bool = True network: str = "mainnet" diff --git a/views_api.py b/views_api.py index e985155..2abd982 100644 --- a/views_api.py +++ b/views_api.py @@ -64,6 +64,7 @@ PreviewAddressRequest, CloudflareConfig, SetupBip353Request, + RecoverKeysRequest ) MAX_ADDRESSES_PER_WALLET = 10 @@ -537,6 +538,53 @@ async def api_broadcast_transaction(data: BroadcastTxRequest): ) +@silnt_api_router.post("/api/v1/wallet/{wallet_id}/recover-keys") +async def api_recover_wallet_keys( + wallet_id: str, + data: RecoverKeysRequest, + key_info: WalletTypeInfo = Depends(require_invoice_key), +): + """ + Re-derive scan_secret and spend_key from mnemonic for an existing wallet. + Verifies the derived sp_address matches the stored one — protects against + re-importing the wrong mnemonic. + Keys are NEVER stored on the server, only returned transiently. + """ + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + if wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + + try: + mnemonic_plain = decrypt_mnemonic(data.mnemonic, str(data.last_height)) + sp_address, scan_secret_hex, spend_key_hex = await generate_silent_wallet_address( + mnemonic_plain, + network=wallet.network, + ) + except Exception as e: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=f"Could not derive keys from mnemonic: {str(e)}", + ) + + # Verify derived address matches the stored one — wrong mnemonic = rejection + if sp_address.lower() != wallet.sp_address.lower(): + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=( + "The mnemonic you entered does not match this wallet. " + "Derived SP address differs from the stored one." + ), + ) + + # Return keys transiently — they are not stored anywhere on the server + return { + "wallet_id": wallet_id, + "scan_secret": scan_secret_hex, + "spend_key": spend_key_hex, + } + @silnt_api_router.get("/api/v1/config") async def api_get_config( key_info: WalletTypeInfo = Depends(require_invoice_key), From e5db8fbae76392bd829fedf5578ec186f786a75e Mon Sep 17 00:00:00 2001 From: Ponthief Date: Sat, 23 May 2026 09:50:39 +0100 Subject: [PATCH 57/83] add user managament for Thrilla --- crud.py | 13 ++ helpers/email_verification.py | 257 ++++++++++++++++++++++++++++++++++ helpers/forgot_password.py | 114 +++++++++++++++ helpers/scan_rate_limiter.py | 111 +++++++++++++++ models.py | 6 +- views_api.py | 105 +++++++++++++- 6 files changed, 598 insertions(+), 8 deletions(-) create mode 100644 helpers/email_verification.py create mode 100644 helpers/forgot_password.py create mode 100644 helpers/scan_rate_limiter.py diff --git a/crud.py b/crud.py index b371f49..ed11452 100644 --- a/crud.py +++ b/crud.py @@ -275,3 +275,16 @@ async def update_cloudflare_config(config: CloudflareConfig) -> CloudflareConfig {"id": CF_CONFIG_ID, "json_data": json_data}, ) return config + +async def count_silnt_wallets(user: str, network: Optional[str] = None) -> int: + if network: + row = await db.fetchone( + 'SELECT COUNT(*) AS c FROM silnt.wallets WHERE "user" = :user AND network = :network', + {"user": user, "network": network}, + ) + else: + row = await db.fetchone( + 'SELECT COUNT(*) AS c FROM silnt.wallets WHERE "user" = :user', + {"user": user}, + ) + return row["c"] if row else 0 \ No newline at end of file diff --git a/helpers/email_verification.py b/helpers/email_verification.py new file mode 100644 index 0000000..4e4444d --- /dev/null +++ b/helpers/email_verification.py @@ -0,0 +1,257 @@ +""" +Forgot-password flow for the siLNt extension. + +Email-verified registration: + 1. Validate the inputs and hash the password + 2. Build a signed token containing username, email, password_hash, timestamp + 3. Email the user a link with the token + 4. When the user clicks the link, decode the token, verify it's not expired, + and create the LNbits account at that moment + 5. Enable default extensions on the new account (since we bypass LNbits's + native register endpoint that normally does this) +""" + +import base64 +import json +import time +from http import HTTPStatus +from typing import Optional +from uuid import uuid4 + +import bcrypt +from fastapi import HTTPException, Request +from loguru import logger +from pydantic import BaseModel + +from lnbits.core.crud import ( + create_account, + get_account_by_username_or_email, +) +from lnbits.core.crud.extensions import update_user_extension +from lnbits.core.models.extensions import UserExtension +from lnbits.core.models import Account +from lnbits.core.services.notifications import send_email_notification +from lnbits.helpers import encrypt_internal_message, decrypt_internal_message +from lnbits.settings import settings, AuthMethods + + +# Token lifetime — how long verification link stays valid +VERIFICATION_TOKEN_TTL_SECONDS = 60 * 60 # 1 hour + + +class RegistrationRequest(BaseModel): + username: str + email: str + password: str + + +class VerifyRegistrationRequest(BaseModel): + token: str + + +def _generate_verification_token( + username: str, email: str, password_hash: str +) -> str: + """Sign a token carrying the pending registration data.""" + payload = { + "kind": "register", + "username": username, + "email": email, + "password_hash": password_hash, + "ts": int(time.time()), + } + payload_json = json.dumps(payload, separators=(",", ":"), ensure_ascii=False) + enc = encrypt_internal_message(payload_json) + if not enc: + raise RuntimeError("Cannot generate verification token.") + return "verify_" + base64.urlsafe_b64encode(enc.encode()).decode().rstrip("=") + + +def _decode_verification_token(token: str) -> Optional[dict]: + """Decode and validate a verification token.""" + if not token.startswith("verify_"): + return None + try: + b64 = token[7:] + padded = b64 + "=" * (-len(b64) % 4) + enc = base64.urlsafe_b64decode(padded).decode() + payload_json = decrypt_internal_message(enc) + if not payload_json: + return None + payload = json.loads(payload_json) + except Exception as exc: + logger.warning(f"Invalid verification token: {exc}") + return None + + if payload.get("kind") != "register": + return None + + ts = payload.get("ts", 0) + if int(time.time()) - int(ts) > VERIFICATION_TOKEN_TTL_SECONDS: + return None + + return payload + + +async def start_registration( + data: RegistrationRequest, request: Request +) -> dict: + """ + Validate inputs, check uniqueness, hash the password, generate a + verification token, and email the link. Does NOT create the account yet. + """ + if not settings.is_auth_method_allowed(AuthMethods.username_and_password): + raise HTTPException( + HTTPStatus.FORBIDDEN, "Username/password auth disabled." + ) + + username = data.username.strip() + email = data.email.strip().lower() + + if len(username) < 3 or len(username) > 32: + raise HTTPException(HTTPStatus.BAD_REQUEST, "Username must be 3–32 chars.") + if "@" not in email: + raise HTTPException(HTTPStatus.BAD_REQUEST, "Invalid email.") + if len(data.password) < 8: + raise HTTPException(HTTPStatus.BAD_REQUEST, "Password too short (min 8).") + + existing = await get_account_by_username_or_email(username) \ + or await get_account_by_username_or_email(email) + if existing: + raise HTTPException( + HTTPStatus.BAD_REQUEST, + "Username or email already in use.", + ) + + password_hash = bcrypt.hashpw( + data.password.encode(), bcrypt.gensalt() + ).decode() + + try: + token = _generate_verification_token(username, email, password_hash) + except Exception as exc: + logger.error(f"Token generation failed: {exc}") + raise HTTPException(HTTPStatus.INTERNAL_SERVER_ERROR, "Could not start registration.") + + origin = request.headers.get("origin") or request.headers.get("referer") or "" + if not origin: + origin = f"https://{request.headers.get('host', '')}" + origin = origin.rstrip("/") + if origin.count("/") > 2: + parts = origin.split("/") + origin = "/".join(parts[:3]) + verify_url = f"{origin}/verify?token={token}" + + subject = "Thrilla — Verify your email" + body = ( + f"Hi {username},\n\n" + f"Thanks for registering for Thrilla. Click the link below to " + f"activate your account:\n\n" + f"{verify_url}\n\n" + f"This link expires in {VERIFICATION_TOKEN_TTL_SECONDS // 60} minutes.\n\n" + f"If you didn't request this, you can safely ignore this email.\n\n" + f"— Thrilla" + ) + + if not settings.lnbits_email_notifications_enabled: + raise HTTPException( + HTTPStatus.INTERNAL_SERVER_ERROR, + "Email notifications disabled — cannot complete registration.", + ) + + try: + result = await send_email_notification( + to_emails=[email], + message=body, + subject=subject, + ) + if result.get("status") != "ok": + logger.error(f"Email send failed: {result.get('message')}") + raise HTTPException( + HTTPStatus.BAD_GATEWAY, + "Could not send verification email — please try again later.", + ) + except HTTPException: + raise + except Exception as exc: + logger.error(f"Email send raised: {exc}") + raise HTTPException( + HTTPStatus.BAD_GATEWAY, + "Could not send verification email — please try again later.", + ) + + logger.info(f"Verification email sent to {email} for pending username {username}") + return { + "success": True, + "message": "Verification email sent. Check your inbox to complete registration.", + "email": email, + } + + +async def complete_registration(token: str) -> dict: + """ + Decode the verification token and create the LNbits account. + Also enables LNBITS_USER_DEFAULT_EXTENSIONS on the new account (since we + bypass LNbits's native /register endpoint that normally does this). + """ + payload = _decode_verification_token(token) + if not payload: + raise HTTPException( + HTTPStatus.BAD_REQUEST, + "Verification link is invalid or has expired. Please register again.", + ) + + username = payload["username"] + email = payload["email"] + password_hash = payload["password_hash"] + + existing = await get_account_by_username_or_email(username) \ + or await get_account_by_username_or_email(email) + if existing: + raise HTTPException( + HTTPStatus.BAD_REQUEST, + "Username or email is no longer available — please register again with a different one.", + ) + + try: + # LNbits Account requires an id — generate a uuid4 hex like LNbits internals do + account_id = uuid4().hex + account = Account( + id = account_id, + username = username, + email = email, + password_hash = password_hash, + ) + await create_account(account=account) + logger.info(f"Email-verified account created: {username} ({email}) id={account_id}") + + # ── Enable LNBITS_USER_DEFAULT_EXTENSIONS on the new account ────────── + # LNbits's native register endpoint does this; we have to mirror it. + try: + default_exts = settings.lnbits_user_default_extensions or [] + for ext_id in default_exts: + # Build UserExtension model — field names match LNbits internals + user_ext = UserExtension( + user=account_id, + extension=ext_id, + active=True, + ) + await update_user_extension(user_extension=user_ext) + logger.info(f"Enabled default extension '{ext_id}' for {account_id}") + except Exception as exc: + logger.warning(f"Could not enable default extensions for {account_id}: {exc}") + + except HTTPException: + raise + except Exception as exc: + logger.error(f"Account creation failed for {username}: {exc}") + raise HTTPException( + HTTPStatus.INTERNAL_SERVER_ERROR, + "Failed to create account. Please try again.", + ) + + return { + "success": True, + "username": username, + "email": email, + } diff --git a/helpers/forgot_password.py b/helpers/forgot_password.py new file mode 100644 index 0000000..076294d --- /dev/null +++ b/helpers/forgot_password.py @@ -0,0 +1,114 @@ +""" +Forgot-password flow for the siLNt extension. + +Generates LNbits-compatible reset keys (same algorithm as the admin endpoint +in user_api.py) and emails them as a clickable link to the user's registered +email address. +""" + +import base64 +import json +import time +from http import HTTPStatus + +from fastapi import APIRouter, HTTPException, Request +from loguru import logger +from pydantic import BaseModel + +from lnbits.core.crud import get_account_by_email +from lnbits.core.services.notifications import send_email_notification +from lnbits.helpers import encrypt_internal_message +from lnbits.settings import settings + +def _generate_reset_key(user_id: str) -> str: + """Generate the same kind of signed reset key LNbits's admin endpoint produces.""" + reset_data = ["reset", user_id, int(time.time())] + reset_data_json = json.dumps(reset_data, separators=(",", ":"), ensure_ascii=False) + enc = encrypt_internal_message(reset_data_json) + if not enc: + raise RuntimeError("Cannot generate reset key.") + reset_key_b64 = base64.b64encode(enc.encode()).decode() + return f"reset_key_{reset_key_b64}" + +async def request_password_reset(email: str, request: Request) -> dict: + """ + Look up account by email, generate reset key, email the link. + Always returns success-style response — never reveals whether the + email exists (prevents email enumeration). + All exceptions caught at the top level to guarantee a dict response. + """ + generic = { + "success": True, + "message": "If an account with that email exists, a reset link has been sent.", + } + + try: + # ── Look up account ─────────────────────────────────────────────────── + account = None + try: + account = await get_account_by_email(email) + except Exception as exc: + logger.warning(f"Forgot-password lookup failed for {email}: {exc}") + return generic + + if not account: + return generic + if account.id == settings.super_user: + logger.warning("Forgot-password attempted for superuser — ignoring.") + return generic + if not account.email: + logger.warning(f"Account {account.id} has no email on file.") + return generic + + # ── Generate reset key ──────────────────────────────────────────────── + try: + reset_key = _generate_reset_key(account.id) + except Exception as exc: + logger.error(f"Reset key generation failed: {exc}") + return generic + + # ── Build reset URL from request origin ─────────────────────────────── + origin = request.headers.get("origin") or request.headers.get("referer") or "" + if not origin: + origin = f"https://{request.headers.get('host', '')}" + origin = origin.rstrip("/") + # If referer has a path, strip it down to origin + if origin.count("/") > 2: + parts = origin.split("/") + origin = "/".join(parts[:3]) + reset_url = f"{origin}/reset?key={reset_key}" + + # ── Compose email ───────────────────────────────────────────────────── + subject = "Thrilla — Password reset request" + body = ( + f"Hi {account.username or 'there'},\n\n" + f"Someone (hopefully you) requested a password reset for your account.\n\n" + f"Click this link to set a new password:\n{reset_url}\n\n" + f"If you didn't request this, you can safely ignore this email.\n\n" + f"— Thrilla" + ) + + # ── Send ────────────────────────────────────────────────────────────── + if not settings.lnbits_email_notifications_enabled: + logger.error("Password reset requested but email notifications disabled in LNbits.") + return generic + + try: + result = await send_email_notification( + to_emails=[account.email], + message=body, + subject=subject, + ) + if result.get("status") != "ok": + logger.error(f"Failed to send reset email: {result.get('message')}") + return generic + logger.info(f"Password reset email sent to {account.email}") + except Exception as exc: + logger.error(f"Failed to send reset email to {account.email}: {exc}") + return generic + + return generic + + except Exception as exc: + logger.error(f"Unexpected error in forgot-password flow: {exc}", exc_info=True) + return generic \ No newline at end of file diff --git a/helpers/scan_rate_limiter.py b/helpers/scan_rate_limiter.py new file mode 100644 index 0000000..561ecbe --- /dev/null +++ b/helpers/scan_rate_limiter.py @@ -0,0 +1,111 @@ +""" +Rate limiting for the scan endpoint. + +BIP-352 scanning is expensive — each block needs tweaks + UTXOs fetched from +BlindBit and EC math per output. Without limits, a single user (intentionally +or via bug) can hammer the oracle. + +Limits enforced: + 1. Per-wallet cooldown: same wallet can't be scanned more often than every N seconds + 2. Concurrent scans per user: only one active scan at a time per user + 3. Per-IP scan starts per hour + 4. Per-user blocks-scanned budget per hour +""" + +import time +from collections import defaultdict +from http import HTTPStatus +from typing import Optional + +from fastapi import HTTPException, Request +from loguru import logger + + +# ── Configurable limits (could live in BlindbitConfig if you want admin UI control) +WALLET_COOLDOWN_SECONDS = 60 # 1 minute between scans of same wallet +MAX_CONCURRENT_PER_USER = 1 # only one active scan per user +MAX_SCAN_STARTS_PER_IP_HR = 30 # 30 scan-starts/hour per IP +MAX_BLOCKS_PER_USER_HR = 500_000 # ~half a million blocks/hour per user + + +# ── State (in-memory — fine for single-process LNbits) ─────────────────────── +_last_scan_time: dict = {} # wallet_id -> ts +_active_scans: dict = defaultdict(set) # user_id -> {wallet_id, ...} +_ip_scan_log: dict = defaultdict(list) # ip -> [ts, ts, ...] +_user_blocks_log: dict = defaultdict(list) # user_id -> [(ts, count), ...] + + +def _prune_old(entries: list, age_seconds: int) -> list: + """Drop entries older than age_seconds. Entries are timestamps or (ts, *) tuples.""" + cutoff = time.time() - age_seconds + return [ + e for e in entries + if (e[0] if isinstance(e, tuple) else e) >= cutoff + ] + + +def check_scan_allowed( + user_id: str, + wallet_id: str, + ip: str, + estimated_blocks: int, +) -> None: + """ + Raise HTTPException(429) if any rate limit would be violated by this scan. + Call this BEFORE starting the scan. Increments counters as side effects. + """ + now = time.time() + + # ── 1. Per-wallet cooldown ──────────────────────────────────────────────── + last_ts = _last_scan_time.get(wallet_id, 0) + if now - last_ts < WALLET_COOLDOWN_SECONDS: + wait = int(WALLET_COOLDOWN_SECONDS - (now - last_ts)) + raise HTTPException( + status_code=HTTPStatus.TOO_MANY_REQUESTS, + detail=f"Wallet was scanned recently. Try again in {wait} seconds.", + ) + + # ── 2. Concurrent scans per user ────────────────────────────────────────── + if len(_active_scans[user_id]) >= MAX_CONCURRENT_PER_USER: + raise HTTPException( + status_code=HTTPStatus.TOO_MANY_REQUESTS, + detail="Another scan is already running on your account. Wait for it to finish.", + ) + + # ── 3. Per-IP scan starts per hour ──────────────────────────────────────── + _ip_scan_log[ip] = _prune_old(_ip_scan_log[ip], 3600) + if len(_ip_scan_log[ip]) >= MAX_SCAN_STARTS_PER_IP_HR: + raise HTTPException( + status_code=HTTPStatus.TOO_MANY_REQUESTS, + detail="Too many scan attempts from this IP. Try again later.", + ) + + # ── 4. Per-user blocks budget per hour ──────────────────────────────────── + _user_blocks_log[user_id] = _prune_old(_user_blocks_log[user_id], 3600) + consumed = sum(count for _ts, count in _user_blocks_log[user_id]) + if consumed + estimated_blocks > MAX_BLOCKS_PER_USER_HR: + remaining = MAX_BLOCKS_PER_USER_HR - consumed + raise HTTPException( + status_code=HTTPStatus.TOO_MANY_REQUESTS, + detail=( + f"Hourly scan budget exceeded ({MAX_BLOCKS_PER_USER_HR:,} blocks/hour). " + f"You have {remaining:,} blocks remaining this hour. " + f"Try a smaller range or wait." + ), + ) + + # All checks passed — record this scan + _last_scan_time[wallet_id] = now + _active_scans[user_id].add(wallet_id) + _ip_scan_log[ip].append(now) + _user_blocks_log[user_id].append((now, estimated_blocks)) + + logger.info( + f"Scan allowed: user={user_id[:8]} wallet={wallet_id[:8]} " + f"blocks={estimated_blocks} ip={ip}" + ) + + +def mark_scan_finished(user_id: str, wallet_id: str) -> None: + """Release the concurrent-scan slot once a scan finishes (success or failure).""" + _active_scans[user_id].discard(wallet_id) \ No newline at end of file diff --git a/models.py b/models.py index 096e7af..aeb7457 100644 --- a/models.py +++ b/models.py @@ -7,7 +7,8 @@ class BlindbitConfig(BaseModel): blindbit_url: str = "" mempool_url: str = "https://mempool.space" - + min_scan_height: int = 0 # 0 = no minimum; e.g. 840000 = no scans before block 840000 + max_wallets_per_user: int = 0 # 0 = unlimited class CreateWallet(BaseModel): mnemonic: str = None @@ -102,3 +103,6 @@ class CloudflareConfig(BaseModel): class SetupBip353Request(BaseModel): username: str # e.g. "alice" → alice@yourdomain.com ttl: int = 300 # DNS TTL in seconds + +class ForgotPasswordRequest(BaseModel): + email: str \ No newline at end of file diff --git a/views_api.py b/views_api.py index 2abd982..0a0ab16 100644 --- a/views_api.py +++ b/views_api.py @@ -26,6 +26,12 @@ CloudflareError, ) +from .helpers.email_verification import ( + RegistrationRequest, VerifyRegistrationRequest, + start_registration, complete_registration, +) +from .helpers.scan_rate_limiter import check_scan_allowed, mark_scan_finished +from .helpers.forgot_password import request_password_reset from .crud import ( get_silnt_wallets, create_silnt_wallet, @@ -50,6 +56,7 @@ delete_wallet_label_addresses, get_cloudflare_config, update_cloudflare_config, + count_silnt_wallets ) from .models import ( @@ -64,7 +71,8 @@ PreviewAddressRequest, CloudflareConfig, SetupBip353Request, - RecoverKeysRequest + RecoverKeysRequest, + ForgotPasswordRequest ) MAX_ADDRESSES_PER_WALLET = 10 @@ -113,6 +121,18 @@ async def api_wallet_create( spend_key="", scan_secret="", ) + # Clamp "Born at Height" to the configured minimum to prevent users + # from creating wallets that would force expensive deep scans. + blindbit_cfg = await get_blindbit_config() + min_height = blindbit_cfg.min_scan_height or 0 + if min_height > 0 and int(data.last_height) < min_height: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=( + f"Wallet birth height must be at least {min_height} on this server. " + f"You entered {data.last_height}." + ), + ) ( sp_address, scan_secret_hex, @@ -131,6 +151,19 @@ async def api_wallet_create( status_code=HTTPStatus.BAD_REQUEST, detail="Silent Payment Wallet already exists!", ) + blindbit_cfg = await get_blindbit_config() + max_wallets = blindbit_cfg.max_wallets_per_user or 0 + if max_wallets > 0: + current_count = await count_silnt_wallets(key_info.wallet.user) + if current_count >= max_wallets: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=( + f"Wallet limit reached. You can have at most {max_wallets} wallet" + f"{'s' if max_wallets != 1 else ''} on this server. " + f"You currently have {current_count}." + ), + ) if data.hr_address: try: resolved = bip353_resolve(data.hr_address) @@ -396,16 +429,46 @@ async def api_scan_wallet( ): wallet = await get_silnt_wallet(wallet_id) if not wallet: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist." - ) - # Ownership guard: users may only scan wallets that belong to them. + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") if wallet.user != key_info.wallet.user: raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + + # Enforce min scan height + blindbit = await get_blindbit_config() + min_height = blindbit.min_scan_height or 0 + + requested_from = data.from_height if data.from_height is not None else wallet.last_height + if min_height > 0 and requested_from < min_height: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=( + f"Scanning below block {min_height} is disabled on this server. " + f"Requested start height was {requested_from}." + ), + ) + + # Estimate block count for budget check + # Use chain tip as fallback if to_height not given + to_height_est = data.to_height + if to_height_est is None: + from .helpers.scan import BlindBitOracleClient + oracle = BlindBitOracleClient(base_url=blindbit.blindbit_url) + to_height_est = await oracle.get_chain_tip() + estimated_blocks = max(1, to_height_est - requested_from) + + client_ip = request.client.host if request.client else "unknown" + + # Rate limit check (raises 429 if any limit exceeded) + check_scan_allowed( + user_id=key_info.wallet.user, + wallet_id=wallet_id, + ip=client_ip, + estimated_blocks=estimated_blocks, + ) try: result = await scan_wallet( wallet_id=wallet_id, - scan_secret_hex=data.scan_secret, # from client request + scan_secret_hex=data.scan_secret, spend_secret_hex=data.spend_key, from_height=data.from_height, to_height=data.to_height, @@ -417,6 +480,9 @@ async def api_scan_wallet( logger.error(f"Scan failed: {e}") raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)) + finally: + # ALWAYS release the concurrent-scan slot, even on error/exception + mark_scan_finished(key_info.wallet.user, wallet_id) @silnt_api_router.post("/api/v1/wallet/{wallet_id}/scan/stop") async def api_stop_scan( @@ -431,6 +497,7 @@ async def api_stop_scan( if wallet.user != key_info.wallet.user: raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") request_scan_stop(wallet_id) + mark_scan_finished(key_info.wallet.user, wallet_id) return {"status": "stop requested"} @@ -591,13 +658,15 @@ async def api_get_config( ) -> dict: blindbit = await get_blindbit_config() config = Config() + current = await count_silnt_wallets(key_info.wallet.user) return { "mempool_endpoint": blindbit.mempool_url or "https://mempool.space", "sats_denominated": config.sats_denominated, "network": config.network, + "min_scan_height": blindbit.min_scan_height or 0, + "wallet_count": current } - @silnt_api_router.get( "/api/v1/wallet/{wallet_id}/scan/progress", dependencies=[Depends(require_invoice_key)], @@ -737,3 +806,25 @@ async def api_delete_bip353( await update_hr_address(wallet_id, "") return {"deleted": deleted, "was": wallet.hr_address} + +@silnt_api_router.post("/api/v1/auth/register-start") +async def api_register_start(data: RegistrationRequest, request: Request) -> dict: + return await start_registration(data, request) + +@silnt_api_router.post("/api/v1/auth/register-verify") +async def api_register_verify(data: VerifyRegistrationRequest) -> dict: + return await complete_registration(data.token) + +@silnt_api_router.post("/api/v1/auth/forgot-password") +async def api_forgot_password(data: ForgotPasswordRequest, request: Request) -> dict: + """ + User requests a password reset link by email. + The link is emailed to them and contains a signed reset_key that can be + submitted to LNbits's PUT /api/v1/auth/reset endpoint. + """ + if not data.email or "@" not in data.email: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail="Valid email address required.", + ) + return await request_password_reset(data.email.strip().lower(), request) \ No newline at end of file From b48ff29cf1a8e29fbd715e42d643cb867173db30 Mon Sep 17 00:00:00 2001 From: Ponthief Date: Wed, 27 May 2026 22:57:49 +0100 Subject: [PATCH 58/83] add device authorisation; email verify; transactions --- crud.py | 493 +++++++++++++++++- helpers/device_auth.py | 138 +++++ helpers/dust_check.py | 116 +++++ helpers/email_verification.py | 97 +++- helpers/scan.py | 43 +- helpers/transactions.py | 172 +++++++ helpers/wallet.py | 176 ++++--- migrations.py | 45 +- models.py | 65 ++- static/components/utxo-list.js | 38 +- static/components/wallet-list.js | 99 ++-- static/js/index.js | 19 +- templates/silnt/components/utxo-list.html | 35 ++ templates/silnt/components/wallet-list.html | 57 ++- templates/silnt/index.html | 19 +- views_api.py | 539 ++++++++++++++++++-- 16 files changed, 1915 insertions(+), 236 deletions(-) create mode 100644 helpers/device_auth.py create mode 100644 helpers/dust_check.py create mode 100644 helpers/transactions.py diff --git a/crud.py b/crud.py index ed11452..dd29652 100644 --- a/crud.py +++ b/crud.py @@ -1,6 +1,6 @@ import json import time -from typing import Optional, Tuple +from typing import Optional, Tuple, List import secrets from lnbits.db import Database from lnbits.helpers import urlsafe_short_hash @@ -11,6 +11,8 @@ UTXORecord, WalletAddress, CloudflareConfig, + UpdateUtxoLabel, + TrustedDevice ) from embit.descriptor import Descriptor, Key @@ -23,7 +25,7 @@ # Singleton row ID for the global blindbit config BLINDBIT_CONFIG_ID = "blindbit" CF_CONFIG_ID = "cloudflare_config" - +BIP352_CHANGE_LABEL_INDEX = 1 async def create_silnt_wallet(wallet: WalletAccount) -> WalletAccount: await db.insert("silnt.wallets", wallet) @@ -149,8 +151,8 @@ async def get_utxos_for_wallet(wallet_id: str) -> list[UTXORecord]: async def insert_utxos_for_wallet(wallet_id: str, utxos: list) -> None: for utxo in utxos: await db.execute( - """INSERT INTO silnt.utxos (txid, vout, amount, priv_key_tweak, pub_key, utxo_state, timestamp, wallet_id) - VALUES (:txid, :vout, :amount, :priv_key_tweak, :pub_key, :utxo_state, :timestamp, :wallet_id) + """INSERT INTO silnt.utxos (txid, vout, amount, priv_key_tweak, pub_key, utxo_state, timestamp, wallet_id, label) + VALUES (:txid, :vout, :amount, :priv_key_tweak, :pub_key, :utxo_state, :timestamp, :wallet_id, :label) ON CONFLICT (txid) DO UPDATE SET amount = EXCLUDED.amount, priv_key_tweak = EXCLUDED.priv_key_tweak, @@ -159,7 +161,9 @@ async def insert_utxos_for_wallet(wallet_id: str, utxos: list) -> None: WHEN silnt.utxos.utxo_state IN ('spent', 'unconfirmed_spent') THEN silnt.utxos.utxo_state ELSE EXCLUDED.utxo_state - END""", + END, + label = COALESCE(silnt.utxos.label, EXCLUDED.label) + """, utxo.to_db_row(wallet_id), ) @@ -177,7 +181,13 @@ async def get_wallet_addresses(wallet_id: str) -> list: {"wallet_id": wallet_id}, ) - +async def get_wallet_address(id: str) -> Optional[WalletAddress]: + return await db.fetchone( + "SELECT * FROM silnt.wallet_addresses WHERE id = :id", + {"id": id}, + WalletAddress + ) + async def count_wallet_addresses(wallet_id: str) -> int: row = await db.fetchone( "SELECT COUNT(*) as cnt FROM silnt.wallet_addresses WHERE wallet_id = :wallet_id", @@ -287,4 +297,473 @@ async def count_silnt_wallets(user: str, network: Optional[str] = None) -> int: 'SELECT COUNT(*) AS c FROM silnt.wallets WHERE "user" = :user', {"user": user}, ) - return row["c"] if row else 0 \ No newline at end of file + return row["c"] if row else 0 + +async def update_utxo_label_by_txid( + txid: str, label: Optional[str], wallet_id: Optional[str] = None +) -> int: + """ + Set or clear the label on UTXO(s) matching the given txid. + Returns the number of rows updated. Empty string label is treated as NULL. + Optionally scoped to a specific wallet_id for safety. + """ + label_value = (label or "").strip() or None + if wallet_id: + result = await db.execute( + """UPDATE silnt.utxos SET label = :label + WHERE txid = :txid AND wallet_id = :wallet_id""", + {"label": label_value, "txid": txid, "wallet_id": wallet_id}, + ) + else: + result = await db.execute( + "UPDATE silnt.utxos SET label = :label WHERE txid = :txid", + {"label": label_value, "txid": txid}, + ) + return getattr(result, "rowcount", 0) or 0 + + +async def get_utxos_by_txid(txid: str) -> list: + """Return all UTXO rows for a given txid (may have multiple vouts).""" + rows = await db.fetchall( + "SELECT * FROM silnt.utxos WHERE txid = :txid", {"txid": txid} + ) + return [UTXORecord(**dict(r)) for r in rows] + +async def get_next_label_index(wallet_id: str) -> int: + row = await db.fetchone( + """SELECT COALESCE(MAX(label_index), 0) AS max_idx + FROM silnt.wallet_addresses + WHERE wallet_id = :wid""", + {"wid": wallet_id}, + ) + next_idx = int((row["max_idx"] or 0)) + 1 + # Skip the BIP-352 change label + if next_idx <= BIP352_CHANGE_LABEL_INDEX: + next_idx = BIP352_CHANGE_LABEL_INDEX + 1 # → 2 + return next_idx + + +async def address_exists(wallet_id: str, sp_address: str) -> bool: + row = await db.fetchone( + """SELECT 1 FROM silnt.wallet_addresses + WHERE wallet_id = :wid AND sp_address = :addr""", + {"wid": wallet_id, "addr": sp_address}, + ) + return row is not None + +async def label_index_taken(wallet_id: str, label_index: int) -> bool: + row = await db.fetchone( + """SELECT 1 FROM silnt.wallet_addresses + WHERE wallet_id = :wid AND label_index = :idx""", + {"wid": wallet_id, "idx": label_index}, + ) + return row is not None + +async def save_wallet_address( + wallet_id: str, + sp_address: str, + label: Optional[str], + label_index: int, +) -> dict: + addr_id = secrets.token_urlsafe(16) + now = int(time.time()) + await db.execute( + """INSERT INTO silnt.wallet_addresses + (id, wallet_id, sp_address, label, label_index, created_at) + VALUES (:id, :wid, :addr, :label, :idx, :ts)""", + { + "id": addr_id, + "wid": wallet_id, + "addr": sp_address, + "label": (label or "").strip() or None, + "idx": label_index, + "ts": now, + }, + ) + return { + "id": addr_id, + "wallet_id": wallet_id, + "sp_address": sp_address, + "label": label, + "label_index": label_index, + "created_at": now, + } + +async def get_unspent_dust_check(wallet_id: str) -> list[dict]: + rows = await db.fetchall( + """SELECT txid, vout, amount, suspected_dust FROM silnt.utxos + WHERE wallet_id = :wid AND utxo_state = 'unspent'""", + {"wid": wallet_id} + ) + return [dict(r) for r in rows] + +async def update_utxo_dust_flag(txid: str, vout: int, flag: bool) -> None: + await db.execute( + """UPDATE silnt.utxos SET suspected_dust = :flag + WHERE txid = :txid AND vout = :vout""", + {"flag": flag, "txid": txid, "vout": vout}, + ) + + +async def update_utxo_frozen(txid: str, vout: int, frozen: bool) -> None: + await db.execute( + """UPDATE silnt.utxos SET frozen = :frozen + WHERE txid = :txid AND vout = :vout""", + {"frozen": frozen, "txid": txid, "vout": vout}, + ) + +async def owner_check_dust(txid: str, vout: int): + return await db.fetchone( + "SELECT wallet_id FROM silnt.utxos WHERE txid = :txid AND vout = :vout", + {"txid": txid, "vout": vout}, + ) + +async def get_eligible_utxos( + wallet_id: str, + txid_vout_pairs: list[tuple[str, int]], +) -> list[dict]: + """ + Return rows from silnt.utxos that are: + - belong to wallet_id + - state = 'unspent' + - NOT frozen + - match one of the (txid, vout) pairs supplied + """ + if not txid_vout_pairs: + return [] + + # Build a parameterized IN-clause using row tuples + placeholders = [] + params = {"wid": wallet_id} + for i, (txid, vout) in enumerate(txid_vout_pairs): + placeholders.append(f"(:t{i}, :v{i})") + params[f"t{i}"] = txid + params[f"v{i}"] = vout + + sql = f""" + SELECT txid, vout, amount FROM silnt.utxos + WHERE wallet_id = :wid + AND utxo_state = 'unspent' + AND COALESCE(frozen, FALSE) = FALSE + AND (txid, vout) IN ({", ".join(placeholders)}) + """ + rows = await db.fetchall(sql, params) + return [dict(r) for r in rows] + +async def update_address_label(addr_id: str, label: Optional[str]) -> int: + """ + Update only the label string on a labeled address. Returns rows affected. + Empty string is stored as NULL. + """ + label_value = (label or "").strip() or None + result = await db.execute( + "UPDATE silnt.wallet_addresses SET label = :label WHERE id = :id", + {"label": label_value, "id": addr_id}, + ) + return getattr(result, "rowcount", 0) or 0 + +async def get_wallet_unspent_utxos_for_dust_check(wallet_id: str) -> list[dict]: + rows = await db.fetchall( + """SELECT txid, vout, amount, suspected_dust + FROM silnt.utxos + WHERE wallet_id = :wid AND utxo_state = 'unspent'""", + {"wid": wallet_id}, + ) + return [dict(r) for r in rows] + + +async def get_wallet_owned_txids(wallet_id: str) -> set[str]: + rows = await db.fetchall( + "SELECT txid FROM silnt.utxos WHERE wallet_id = :wid", + {"wid": wallet_id}, + ) + return {r["txid"] for r in rows} + + +async def mark_utxos_spent_by_tx( + wallet_id: str, + input_outpoints: list[tuple[str, int]], + spending_txid: str, +) -> int: + """Mark UTXOs as spent by a tx we broadcast — also records spent_at timestamp.""" + if not input_outpoints: + return 0 + now = int(time.time()) + + placeholders = [] + params = { + "wid": wallet_id, + "spending_txid": spending_txid, + "spent_at": now, + } + for i, (in_txid, in_vout) in enumerate(input_outpoints): + placeholders.append(f"(:t{i}, :v{i})") + params[f"t{i}"] = in_txid + params[f"v{i}"] = in_vout + + sql = f""" + UPDATE silnt.utxos + SET utxo_state = 'unconfirmed_spent', + spent_in_txid = :spending_txid, + spent_at = :spent_at + WHERE wallet_id = :wid + AND (txid, vout) IN ({", ".join(placeholders)}) + """ + result = await db.execute(sql, params) + return getattr(result, "rowcount", 0) or 0 + + +async def is_own_sent_tx(wallet_id: str, txid: str) -> bool: + """ + Check if this wallet has broadcast a transaction with this txid. + A row exists with spent_in_txid = txid iff we broadcast it. + """ + row = await db.fetchone( + """SELECT 1 FROM silnt.utxos + WHERE wallet_id = :wid AND spent_in_txid = :txid + LIMIT 1""", + {"wid": wallet_id, "txid": txid}, + ) + return row is not None + +async def get_wallet_owned_outpoints(wallet_id: str) -> set[tuple[str, int]]: + """ + All (txid, vout) outpoints this wallet has ever owned, regardless of state. + Used to classify funding-tx inputs as self-send vs external. + """ + rows = await db.fetchall( + "SELECT txid, vout FROM silnt.utxos WHERE wallet_id = :wid", + {"wid": wallet_id}, + ) + return {(r["txid"], int(r["vout"])) for r in rows} + +async def get_utxo_freeze_reason(txid: str, vout: int) -> Optional[str]: + """Return current freeze_reason ('auto'|'manual'|None) for a UTXO.""" + row = await db.fetchone( + "SELECT freeze_reason FROM silnt.utxos WHERE txid = :txid AND vout = :vout", + {"txid": txid, "vout": vout}, + ) + return row["freeze_reason"] if row else None + +async def set_utxo_freeze_auto(txid: str, vout: int) -> None: + """Mark a UTXO as auto-frozen (dust eval owns this lock).""" + await db.execute( + """UPDATE silnt.utxos + SET frozen = TRUE, freeze_reason = 'auto' + WHERE txid = :txid AND vout = :vout + AND (freeze_reason IS NULL OR freeze_reason = 'auto') + """, + + {"txid": txid, "vout": vout}, + ) + + +async def set_utxo_freeze_manual(txid: str, vout: int) -> None: + """Mark a UTXO as manually frozen (user owns this lock).""" + await db.execute( + """UPDATE silnt.utxos + SET frozen = TRUE, freeze_reason = 'manual' + WHERE txid = :txid AND vout = :vout""", + {"txid": txid, "vout": vout}, + ) + + +async def clear_utxo_freeze_auto(txid: str, vout: int) -> None: + """ + Clear an auto-freeze. NO-OP if the UTXO was manually frozen — only the + user (via the unfreeze endpoint) can clear those. + """ + await db.execute( + """UPDATE silnt.utxos + SET frozen = FALSE, freeze_reason = NULL + WHERE txid = :txid AND vout = :vout AND freeze_reason = 'auto'""", + {"txid": txid, "vout": vout}, + ) + + +async def clear_utxo_freeze_manual(txid: str, vout: int) -> None: + """User-initiated unfreeze — clears regardless of who set it.""" + await db.execute( + """UPDATE silnt.utxos + SET frozen = FALSE, freeze_reason = NULL + WHERE txid = :txid AND vout = :vout""", + {"txid": txid, "vout": vout}, + ) + +async def get_wallet_receives(wallet_id: str) -> list[dict]: + """ + Group all owned UTXOs by funding txid. Each row = one tx where we received. + Returns: [{txid, timestamp, output_sum, output_count, labels[]}, ...] + """ + rows = await db.fetchall( + """ + SELECT + txid, + MIN(timestamp) AS timestamp, + SUM(amount) AS output_sum, + COUNT(*) AS output_count, + ARRAY_REMOVE(ARRAY_AGG(DISTINCT label), NULL) AS labels + FROM silnt.utxos + WHERE wallet_id = :wid + GROUP BY txid + """, + {"wid": wallet_id}, + ) + return [ + { + "txid": r["txid"], + "timestamp": int(r["timestamp"] or 0), + "output_sum": int(r["output_sum"] or 0), + "output_count": int(r["output_count"] or 0), + "labels": list(r["labels"] or []), + } + for r in rows + ] + + +async def get_wallet_sends(wallet_id: str) -> list[dict]: + """ + Group all UTXOs we've spent by spent_in_txid. Each row = one tx we sent. + Returns: [{txid, spent_at, input_sum, input_count}, ...] + """ + rows = await db.fetchall( + """ + SELECT + spent_in_txid AS txid, + MIN(spent_at) AS spent_at, + SUM(amount) AS input_sum, + COUNT(*) AS input_count + FROM silnt.utxos + WHERE wallet_id = :wid AND spent_in_txid IS NOT NULL + GROUP BY spent_in_txid + """, + {"wid": wallet_id}, + ) + return [ + { + "txid": r["txid"], + "spent_at": int(r["spent_at"] or 0), + "input_sum": int(r["input_sum"] or 0), + "input_count": int(r["input_count"] or 0), + } + for r in rows + ] + + +async def get_utxos_for_txid(wallet_id: str, txid: str) -> list[dict]: + """All UTXOs we own at a given funding txid (for the detail view).""" + rows = await db.fetchall( + """SELECT txid, vout, amount, label, label_index, utxo_state, timestamp + FROM silnt.utxos + WHERE wallet_id = :wid AND txid = :txid + ORDER BY vout""", + {"wid": wallet_id, "txid": txid}, + ) + return [dict(r) for r in rows] + + +async def get_utxos_spent_in_tx(wallet_id: str, txid: str) -> list[dict]: + """All UTXOs we spent in a given tx (for the detail view's input list).""" + rows = await db.fetchall( + """SELECT txid, vout, amount, label, label_index, utxo_state, timestamp, spent_at + FROM silnt.utxos + WHERE wallet_id = :wid AND spent_in_txid = :txid + ORDER BY timestamp""", + {"wid": wallet_id, "txid": txid}, + ) + return [dict(r) for r in rows] + + +async def get_owned_pubkeys(wallet_id: str) -> set[str]: + """All x-only output pubkeys this wallet has ever owned — used to filter + out own change from a send tx's outputs (anything not in this set is + treated as a recipient).""" + rows = await db.fetchall( + "SELECT pub_key FROM silnt.utxos WHERE wallet_id = :wid", + {"wid": wallet_id}, + ) + return {r["pub_key"] for r in rows if r["pub_key"]} + +async def add_trusted_device( + user_id: str, + device_id: str, + user_agent: Optional[str], + ip: Optional[str], + label: Optional[str] = None, +) -> dict: + now = int(time.time()) + row_id = secrets.token_urlsafe(16) + await db.execute( + """INSERT INTO silnt.trusted_devices + (id, user_id, device_id, user_agent, ip, label, confirmed_at, last_seen_at) + VALUES (:id, :uid, :did, :ua, :ip, :label, :ts, :ts) + ON CONFLICT (user_id, device_id) DO UPDATE + SET last_seen_at = EXCLUDED.last_seen_at, + user_agent = EXCLUDED.user_agent, + ip = EXCLUDED.ip""", + { + "id": row_id, + "uid": user_id, + "did": device_id, + "ua": (user_agent or "")[:512], + "ip": (ip or "")[:64], + "label": label, + "ts": now, + }, + ) + return {"id": row_id, "device_id": device_id, "confirmed_at": now} + + +async def get_trusted_device(user_id: str, device_id: str) -> Optional[TrustedDevice]: + row = await db.fetchone( + """SELECT * FROM silnt.trusted_devices + WHERE user_id = :uid AND device_id = :did""", + {"uid": user_id, "did": device_id}, + ) + return TrustedDevice(**dict(row)) if row else None + + +async def list_trusted_devices(user_id: str) -> List[TrustedDevice]: + rows = await db.fetchall( + """SELECT * FROM silnt.trusted_devices + WHERE user_id = :uid + ORDER BY confirmed_at DESC""", + {"uid": user_id}, + ) + return [TrustedDevice(**dict(r)) for r in rows] + + +async def count_trusted_devices(user_id: str) -> int: + row = await db.fetchone( + "SELECT COUNT(*) AS c FROM silnt.trusted_devices WHERE user_id = :uid", + {"uid": user_id}, + ) + return int(row["c"] or 0) + + +async def revoke_trusted_device(user_id: str, device_row_id: str) -> int: + result = await db.execute( + """DELETE FROM silnt.trusted_devices + WHERE user_id = :uid AND id = :id""", + {"uid": user_id, "id": device_row_id}, + ) + return getattr(result, "rowcount", 0) or 0 + + +async def revoke_all_other_devices(user_id: str, keep_device_id: str) -> int: + result = await db.execute( + """DELETE FROM silnt.trusted_devices + WHERE user_id = :uid AND device_id != :keep""", + {"uid": user_id, "keep": keep_device_id}, + ) + return getattr(result, "rowcount", 0) or 0 + + +async def touch_trusted_device(user_id: str, device_id: str) -> None: + """Update last_seen_at when the device makes a request.""" + await db.execute( + """UPDATE silnt.trusted_devices + SET last_seen_at = :ts + WHERE user_id = :uid AND device_id = :did""", + {"uid": user_id, "did": device_id, "ts": int(time.time())}, + ) \ No newline at end of file diff --git a/helpers/device_auth.py b/helpers/device_auth.py new file mode 100644 index 0000000..cec60ea --- /dev/null +++ b/helpers/device_auth.py @@ -0,0 +1,138 @@ +import base64 +import hmac +import hashlib +import json +import time +from typing import Optional +from fastapi import Cookie, Depends, HTTPException, Request, Response +from http import HTTPStatus +from loguru import logger +from lnbits.settings import settings as lnbits_settings +# Variant for admin-key routes: +from lnbits.decorators import require_admin_key +from lnbits.decorators import WalletTypeInfo, require_invoice_key +from ..crud import get_trusted_device, touch_trusted_device + +MAX_TRUSTED_DEVICES_PER_USER = 3 +DEVICE_COOKIE_NAME = "silnt_device_id" +DEVICE_COOKIE_MAX_AGE = 365 * 24 * 3600 # 1 year +DEVICE_CONFIRM_TOKEN_TTL = 3600 # 1 hour + +def _hmac_sign(payload: str) -> str: + key = (lnbits_settings.auth_secret_key or "").encode() + if not key: + raise RuntimeError("LNBITS_AUTH_SECRET_KEY is not set — required for device tokens.") + return base64.urlsafe_b64encode( + hmac.new(key, payload.encode(), hashlib.sha256).digest() + ).rstrip(b"=").decode() + + +def make_device_confirm_token(user_id: str, device_id: str, ua: str, ip: str) -> str: + """Build a signed token for the email-confirmation link.""" + payload = { + "user_id": user_id, + "device_id": device_id, + "ua": (ua or "")[:512], + "ip": (ip or "")[:64], + "exp": int(time.time()) + DEVICE_CONFIRM_TOKEN_TTL, + } + body = base64.urlsafe_b64encode( + json.dumps(payload, separators=(",", ":")).encode() + ).rstrip(b"=").decode() + sig = _hmac_sign(body) + return f"{body}.{sig}" + + +def verify_device_confirm_token(token: str) -> Optional[dict]: + try: + body, sig = token.split(".", 1) + except ValueError: + return None + expected = _hmac_sign(body) + if not hmac.compare_digest(sig, expected): + return None + try: + # Re-pad base64 + padding = "=" * (-len(body) % 4) + payload = json.loads(base64.urlsafe_b64decode(body + padding).decode()) + except Exception: + return None + if payload.get("exp", 0) < int(time.time()): + return None + return payload + + +def set_device_cookie(response: Response, device_id: str) -> None: + """Set the HttpOnly device_id cookie. Same-site + secure.""" + response.set_cookie( + key = DEVICE_COOKIE_NAME, + value = device_id, + max_age = DEVICE_COOKIE_MAX_AGE, + httponly = True, + secure = True, + samesite = "lax", # 'strict' breaks the email-link redirect — lax is fine + path = "/", + ) + + +def get_client_ip(request: Request) -> str: + """Best-effort IP extraction — checks X-Forwarded-For first (Caddy proxy).""" + xff = request.headers.get("x-forwarded-for", "") + if xff: + return xff.split(",")[0].strip() + return request.client.host if request.client else "" + + +async def require_trusted_device( + request: Request, + key_info: WalletTypeInfo = Depends(require_invoice_key), + silnt_device_id: Optional[str] = Cookie(default=None), +) -> WalletTypeInfo: + """ + Combined dependency: validates the API key AND the device cookie. + Use this in place of `require_invoice_key` on every endpoint that should + require a trusted device. + """ + if not silnt_device_id: + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, + detail="device-not-trusted: no device cookie present", + ) + + device = await get_trusted_device(key_info.wallet.user, silnt_device_id) + if not device: + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, + detail="device-not-trusted: device not in trusted list", + ) + + # Track last seen (fire-and-forget; don't fail the request if this fails) + try: + await touch_trusted_device(key_info.wallet.user, silnt_device_id) + except Exception as e: + logger.warning(f"touch_trusted_device failed: {e}") + + return key_info + + +async def require_trusted_device_admin( + request: Request, + key_info: WalletTypeInfo = Depends(require_admin_key), + silnt_device_id: Optional[str] = Cookie(default=None), +) -> WalletTypeInfo: + if not silnt_device_id: + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, + detail="device-not-trusted: no device cookie present", + ) + device = await get_trusted_device(key_info.wallet.user, silnt_device_id) + if not device: + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, + detail="device-not-trusted: device not in trusted list", + ) + try: + await touch_trusted_device(key_info.wallet.user, silnt_device_id) + except Exception as e: + logger.warning(f"touch_trusted_device failed: {e}") + return key_info diff --git a/helpers/dust_check.py b/helpers/dust_check.py new file mode 100644 index 0000000..819c6a5 --- /dev/null +++ b/helpers/dust_check.py @@ -0,0 +1,116 @@ +import httpx +from loguru import logger +from ..crud import ( + get_blindbit_config, + get_wallet_unspent_utxos_for_dust_check, + get_wallet_owned_outpoints, + is_own_sent_tx, + update_utxo_dust_flag, + set_utxo_freeze_auto, + clear_utxo_freeze_auto, + get_utxo_freeze_reason +) + + +async def _funding_tx_inputs_match_owned( + txid: str, + owned_outpoints: set[tuple[str, int]], + mempool_base: str, +) -> bool: + base = mempool_base.rstrip("/") + try: + async with httpx.AsyncClient(timeout=10.0) as c: + r = await c.get(f"{base}/api/tx/{txid}") + if r.status_code != 200: + return False + tx = r.json() + + input_outpoints: set[tuple[str, int]] = set() + for vin in tx.get("vin", []): + in_txid = vin.get("txid") + in_vout = vin.get("vout") + if in_txid is None or in_vout is None: + continue + try: + input_outpoints.add((in_txid, int(in_vout))) + except (TypeError, ValueError): + continue + + return bool(input_outpoints & owned_outpoints) + except Exception as e: + logger.warning(f"Dust check: could not fetch tx {txid}: {e}") + return False + + +async def evaluate_dust_for_wallet(wallet_id: str) -> int: + """ + Reconcile suspected_dust + auto-freeze state for every unspent UTXO. + + Idempotent: produces the correct (dust, frozen, freeze_reason) tuple for + each UTXO regardless of prior state. Manual freezes are never touched. + + Returns the number of UTXOs that transitioned from non-dust to dust on + this run (useful for the "flagged N new dust UTXO(s)" log line). + """ + blindbit = await get_blindbit_config() + threshold = int(blindbit.dust_threshold_sats or 5000) + mempool = blindbit.mempool_url or "https://mempool.space" + + utxos = await get_wallet_unspent_utxos_for_dust_check(wallet_id) + owned_outpoints = await get_wallet_owned_outpoints(wallet_id) + + logger.info( + f"Dust eval: wallet={wallet_id} threshold={threshold} " + f"unspent_count={len(utxos)} owned_outpoints={len(owned_outpoints)}" + ) + + newly_flagged = 0 + + for u in utxos: + amount = int(u.get("amount") or 0) + utxo_txid = u.get("txid") or "" + utxo_vout = int(u.get("vout") or 0) + current_dust = bool(u.get("suspected_dust") or False) + + if not utxo_txid: + continue + + # Determine the correct classification for this UTXO + if amount > threshold: + should_be_dust = False + else: + is_self_send = await is_own_sent_tx(wallet_id, utxo_txid) + if not is_self_send: + is_self_send = await _funding_tx_inputs_match_owned( + utxo_txid, owned_outpoints, mempool + ) + should_be_dust = not is_self_send + + logger.info( + f" utxo {utxo_txid[:12]}:{utxo_vout} amount={amount} " + f"current_dust={current_dust} should_be_dust={should_be_dust}" + ) + + # Reconcile state — always make the DB match the classification + if should_be_dust: + # Ensure suspected_dust=TRUE AND freeze_reason='auto' + if not current_dust: + await update_utxo_dust_flag(utxo_txid, utxo_vout, True) + newly_flagged += 1 + # Always ensure auto-freeze is set when classified as dust. + # set_utxo_freeze_auto only writes freeze_reason='auto'; it does + # NOT clobber existing manual freezes (the WHERE in the UPDATE + # filters by current state, or the helper should — see note). + current_reason = await get_utxo_freeze_reason(utxo_txid, utxo_vout) + if current_reason != "manual": + await set_utxo_freeze_auto(utxo_txid, utxo_vout) + else: + # Ensure suspected_dust=FALSE; release any auto-freeze (leave manual) + if current_dust: + await update_utxo_dust_flag(utxo_txid, utxo_vout, False) + await clear_utxo_freeze_auto(utxo_txid, utxo_vout) + + if newly_flagged: + logger.info(f"Wallet {wallet_id}: flagged {newly_flagged} new dust UTXO(s)") + + return newly_flagged \ No newline at end of file diff --git a/helpers/email_verification.py b/helpers/email_verification.py index 4e4444d..dfa08a1 100644 --- a/helpers/email_verification.py +++ b/helpers/email_verification.py @@ -1,14 +1,17 @@ """ -Forgot-password flow for the siLNt extension. - -Email-verified registration: - 1. Validate the inputs and hash the password - 2. Build a signed token containing username, email, password_hash, timestamp - 3. Email the user a link with the token - 4. When the user clicks the link, decode the token, verify it's not expired, - and create the LNbits account at that moment - 5. Enable default extensions on the new account (since we bypass LNbits's - native register endpoint that normally does this) +Email-verified registration for the siLNt extension. + +Flow: + 1. User submits registration → validate inputs, hash password + 2. Generate a signed token containing {username, email, password_hash, ts} + and email it as a clickable link — NO account is created yet + 3. User clicks the link → decode/validate token (incl. 1-hour TTL) + 4. Create LNbits Account with a fresh uuid4 id + bcrypt password hash + 5. Enable LNBITS_USER_DEFAULT_EXTENSIONS on the new account, marking paid + extensions as already-paid so they bypass the payment requirement + +This guarantees the account is only created after email ownership is proven, +and that siLNt is fully active on first login (paid or not). """ import base64 @@ -27,9 +30,13 @@ create_account, get_account_by_username_or_email, ) -from lnbits.core.crud.extensions import update_user_extension -from lnbits.core.models.extensions import UserExtension +from lnbits.core.crud.extensions import ( + create_user_extension, + update_user_extension, + get_user_extension, +) from lnbits.core.models import Account +from lnbits.core.models.extensions import UserExtension, UserExtensionInfo from lnbits.core.services.notifications import send_email_notification from lnbits.helpers import encrypt_internal_message, decrypt_internal_message from lnbits.settings import settings, AuthMethods @@ -49,6 +56,8 @@ class VerifyRegistrationRequest(BaseModel): token: str +# ── Token helpers ───────────────────────────────────────────────────────────── + def _generate_verification_token( username: str, email: str, password_hash: str ) -> str: @@ -68,7 +77,7 @@ def _generate_verification_token( def _decode_verification_token(token: str) -> Optional[dict]: - """Decode and validate a verification token.""" + """Decode and validate a verification token. Returns None if invalid/expired.""" if not token.startswith("verify_"): return None try: @@ -93,6 +102,8 @@ def _decode_verification_token(token: str) -> Optional[dict]: return payload +# ── Start registration: send email ──────────────────────────────────────────── + async def start_registration( data: RegistrationRequest, request: Request ) -> dict: @@ -133,6 +144,7 @@ async def start_registration( logger.error(f"Token generation failed: {exc}") raise HTTPException(HTTPStatus.INTERNAL_SERVER_ERROR, "Could not start registration.") + # Resolve frontend origin so the link points at the Thrilla domain origin = request.headers.get("origin") or request.headers.get("referer") or "" if not origin: origin = f"https://{request.headers.get('host', '')}" @@ -188,11 +200,13 @@ async def start_registration( } +# ── Complete registration: create account + enable extensions ───────────────── + async def complete_registration(token: str) -> dict: """ Decode the verification token and create the LNbits account. - Also enables LNBITS_USER_DEFAULT_EXTENSIONS on the new account (since we - bypass LNbits's native /register endpoint that normally does this). + Enables LNBITS_USER_DEFAULT_EXTENSIONS on the new account, marking paid + extensions as already-paid (so e.g. siLNt activates without payment). """ payload = _decode_verification_token(token) if not payload: @@ -214,7 +228,7 @@ async def complete_registration(token: str) -> dict: ) try: - # LNbits Account requires an id — generate a uuid4 hex like LNbits internals do + # LNbits Account requires an id field — generate a uuid4 hex account_id = uuid4().hex account = Account( id = account_id, @@ -225,19 +239,28 @@ async def complete_registration(token: str) -> dict: await create_account(account=account) logger.info(f"Email-verified account created: {username} ({email}) id={account_id}") - # ── Enable LNBITS_USER_DEFAULT_EXTENSIONS on the new account ────────── - # LNbits's native register endpoint does this; we have to mirror it. + # Enable LNBITS_USER_DEFAULT_EXTENSIONS — paid bypass for paid extensions try: default_exts = settings.lnbits_user_default_extensions or [] for ext_id in default_exts: - # Build UserExtension model — field names match LNbits internals user_ext = UserExtension( user=account_id, extension=ext_id, active=True, + extra=UserExtensionInfo( + paid_to_enable=True, + payment_hash_to_enable="default_enabled", + ), ) - await update_user_extension(user_extension=user_ext) - logger.info(f"Enabled default extension '{ext_id}' for {account_id}") + # INSERT new row — update_user_extension only modifies existing rows + # so we must use create_user_extension for new accounts. + # If a row already exists for some reason, fall through to update. + existing = await get_user_extension(account_id, ext_id) + if existing: + await update_user_extension(user_extension=user_ext) + else: + await create_user_extension(user_extension=user_ext) + logger.info(f"Enabled default extension '{ext_id}' for {account_id} (paid bypass)") except Exception as exc: logger.warning(f"Could not enable default extensions for {account_id}: {exc}") @@ -250,6 +273,38 @@ async def complete_registration(token: str) -> dict: "Failed to create account. Please try again.", ) + # ── Send welcome email — non-fatal if it fails ──────────────────────────── + try: + welcome_subject = "Welcome to Thrilla" + welcome_body = ( + f"Hi {username},\n\n" + f"Your Thrilla account is now active. You can sign in any time at the " + f"URL below using your username and password.\n\n" + f"What you can do with Thrilla:\n" + f" • Create Silent Payment (BIP-352) wallets — private by default\n" + f" • Scan the chain for incoming payments via your BlindBit oracle\n" + f" • Send to sp1… / bc1q… / BIP-353 (alice@domain) recipients\n" + f" • Register a BIP-353 human-readable address for your wallet\n\n" + f"Wallet keys are stored ONLY on your device — never on the server. " + f"Keep your mnemonic safe; without it your funds can't be recovered.\n\n" + f"If you ever need to reset your password, use the 'Forgot password' " + f"link on the sign-in screen.\n\n" + f"— Thrilla" + ) + if settings.lnbits_email_notifications_enabled: + res = await send_email_notification( + to_emails=[email], + message=welcome_body, + subject=welcome_subject, + ) + if res.get("status") == "ok": + logger.info(f"Welcome email sent to {email}") + else: + logger.warning(f"Welcome email send returned: {res.get('message')}") + except Exception as exc: + # Welcome email failure must not block account activation + logger.warning(f"Could not send welcome email to {email}: {exc}") + return { "success": True, "username": username, diff --git a/helpers/scan.py b/helpers/scan.py index 7506341..b1077e7 100644 --- a/helpers/scan.py +++ b/helpers/scan.py @@ -18,11 +18,11 @@ insert_utxos_for_wallet, update_balance, ) - +from .dust_check import evaluate_dust_for_wallet _scan_progress: dict[str, dict] = {} _scan_stop: dict[str, bool] = {} SECP256K1_N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - +BIP352_CHANGE_LABEL_INDEX = 1 @dataclass class Label: @@ -49,6 +49,7 @@ class OwnedUTXO: utxo_state: str timestamp: int = 0 label: Optional[Label] = None + label_text: Optional[str] = None def to_db_row(self, wallet_id: str) -> dict: return { @@ -60,6 +61,7 @@ def to_db_row(self, wallet_id: str) -> dict: "utxo_state": self.utxo_state, "timestamp": self.timestamp, "wallet_id": wallet_id, + "label": self.label_text } @@ -141,7 +143,8 @@ def create_label(scan_key: bytes, m: int) -> Label: def create_labels(scan_key: bytes, indices: list[int]) -> list[Label]: - return [create_label(scan_key, m) for m in sorted(set([0] + indices))] + all_indices = sorted(set([0, BIP352_CHANGE_LABEL_INDEX] + list(indices))) + return [create_label(scan_key, m) for m in all_indices] def match_labels( @@ -534,7 +537,11 @@ async def scan_wallet( labels = create_labels( scan_secret_bytes, indices=[a.label_index for a in saved_addresses] ) - + addr_label_map: dict[int, str] = { + a.label_index: a.label + for a in saved_addresses + if getattr(a, "label", None) + } total_found = 0 blocks_scanned = 0 last_scanned_height = start @@ -585,9 +592,25 @@ async def scan_wallet( logger.error(f"Block {h} error: {result}") continue if result: - await insert_utxos_for_wallet(wallet_id, result) - total_found += len(result) - logger.info(f"Block {h}: {len(result)} UTXOs") + # Inherit address labels onto matching UTXOs (added earlier) + for owned in result: + if owned.label and owned.label.m in addr_label_map: + owned.label_text = addr_label_map[owned.label.m] + try: + await insert_utxos_for_wallet(wallet_id, result) + total_found += len(result) + logger.info(f"Block {h}: {len(result)} UTXOs") + except Exception as ins_err: + # Log full DB error server-side for the admin to investigate, + # but don't crash the whole scan — just skip this block's results + logger.error( + f"Block {h}: found {len(result)} UTXO(s) but DB insert failed: {ins_err}" + ) + # Bubble up a clean signal to the caller + raise RuntimeError( + f"Found UTXO(s) at block {h} but they could not be saved. " + f"Please contact your administrator. (Internal error: insert failed)" + ) blocks_scanned += 1 last_scanned_height = h @@ -605,6 +628,12 @@ async def scan_wallet( ) balance = sum(r["amount"] for r in unspent) await update_balance(wallet_id, balance) + try: + newly_flagged = await evaluate_dust_for_wallet(wallet_id) + if newly_flagged > 0: + logger.info(f"Wallet {wallet_id}: flagged {newly_flagged} new dust UTXO(s)") + except Exception as e: + logger.warning(f"Dust evaluation failed for {wallet_id}: {e}") logger.info( f"Scan done: {blocks_scanned} blocks, {total_found} UTXOs, balance={balance}" ) diff --git a/helpers/transactions.py b/helpers/transactions.py new file mode 100644 index 0000000..a6add0a --- /dev/null +++ b/helpers/transactions.py @@ -0,0 +1,172 @@ +import time +import httpx +from loguru import logger +from ..crud import ( + get_blindbit_config, + get_wallet_receives, + get_wallet_sends, + get_utxos_for_txid, + get_utxos_spent_in_tx, + get_owned_pubkeys, +) + + +# Per-process in-memory cache. Keyed by (mempool_base, txid). +# Acceptable to lose on restart — this is non-critical metadata. +_TX_CACHE: dict[tuple[str, str], tuple[float, dict]] = {} +_TX_CACHE_TTL = 3600 # 1 hour + + +async def _fetch_tx_from_mempool(txid: str, mempool_base: str) -> dict | None: + """Fetch a tx's full mempool.space data, cached for 1hr.""" + key = (mempool_base, txid) + now = time.time() + cached = _TX_CACHE.get(key) + if cached and now - cached[0] < _TX_CACHE_TTL: + return cached[1] + + base = mempool_base.rstrip("/") + try: + async with httpx.AsyncClient(timeout=10.0) as c: + r = await c.get(f"{base}/api/tx/{txid}") + if r.status_code != 200: + return None + data = r.json() + _TX_CACHE[key] = (now, data) + return data + except Exception as e: + logger.warning(f"Tx fetch failed for {txid}: {e}") + return None + + +async def list_wallet_transactions( + wallet_id: str, + limit: int = 50, + offset: int = 0, +) -> list[dict]: + """ + Build the combined chronological transaction list. No mempool calls here — + everything from local DB. Fast. + + Each row: + { kind: 'receive'|'send'|'self_send', + txid, timestamp, amount_sats, + input_sum, output_sum, # both populated for self_send + output_count, input_count, + labels: [str], + confirmed: bool # heuristic from UTXO state + } + """ + receives = {r["txid"]: r for r in await get_wallet_receives(wallet_id)} + sends = {s["txid"]: s for s in await get_wallet_sends(wallet_id)} + + txids = set(receives) | set(sends) + rows = [] + for txid in txids: + rcv = receives.get(txid) + snd = sends.get(txid) + + if snd and rcv: + kind = "self_send" + timestamp = snd["spent_at"] or rcv["timestamp"] + # Net amount = what came back minus what went out (negative = net outflow, + # equals fee + any external recipient amount) + amount_sats = rcv["output_sum"] - snd["input_sum"] + labels = rcv["labels"] + input_sum = snd["input_sum"] + output_sum = rcv["output_sum"] + input_count = snd["input_count"] + output_count= rcv["output_count"] + elif snd: + kind = "send" + timestamp = snd["spent_at"] + amount_sats = -snd["input_sum"] # fully outgoing (will refine on detail) + labels = [] + input_sum = snd["input_sum"] + output_sum = 0 + input_count = snd["input_count"] + output_count= 0 + else: + kind = "receive" + timestamp = rcv["timestamp"] + amount_sats = rcv["output_sum"] + labels = rcv["labels"] + input_sum = 0 + output_sum = rcv["output_sum"] + input_count = 0 + output_count= rcv["output_count"] + + rows.append({ + "kind": kind, + "txid": txid, + "timestamp": timestamp, + "amount_sats": amount_sats, + "input_sum": input_sum, + "output_sum": output_sum, + "input_count": input_count, + "output_count": output_count, + "labels": labels, + }) + + # Newest first + rows.sort(key=lambda r: r["timestamp"], reverse=True) + return rows[offset:offset + limit] + + +async def get_wallet_transaction_detail( + wallet_id: str, + txid: str, +) -> dict: + """ + Enriched view of one transaction. Pulls our own UTXOs from DB, then queries + mempool.space for the full tx (fee, recipient, confirmation status). + """ + blindbit = await get_blindbit_config() + mempool_base = blindbit.mempool_url or "https://mempool.space" + + own_outputs = await get_utxos_for_txid(wallet_id, txid) + spent_inputs = await get_utxos_spent_in_tx(wallet_id, txid) + owned_pubkeys = await get_owned_pubkeys(wallet_id) + tx = await _fetch_tx_from_mempool(txid, mempool_base) + + detail = { + "txid": txid, + "own_outputs": own_outputs, + "spent_inputs": spent_inputs, + "fee_sats": None, + "recipients": [], # outputs NOT owned by us + "confirmed": None, + "block_height": None, + "block_time": None, + "explorer_url": f"{mempool_base.rstrip('/')}/tx/{txid}", + } + + if tx is None: + return detail + + # Fee + detail["fee_sats"] = tx.get("fee") + + # Confirmation + status = tx.get("status", {}) + detail["confirmed"] = bool(status.get("confirmed")) + detail["block_height"] = status.get("block_height") + detail["block_time"] = status.get("block_time") + + # Recipients = outputs whose x-only key is NOT one of ours + for vout_data in tx.get("vout", []): + spk_asm = vout_data.get("scriptpubkey_asm") or "" + # Taproot: "OP_PUSHNUM_1 OP_PUSHBYTES_32 " + xonly = None + parts = spk_asm.split() + if len(parts) >= 3 and parts[0] == "OP_PUSHNUM_1": + xonly = parts[-1] + if xonly and xonly in owned_pubkeys: + continue + detail["recipients"].append({ + "address": vout_data.get("scriptpubkey_address"), + "amount": int(vout_data.get("value") or 0), + "type": vout_data.get("scriptpubkey_type"), + }) + + return detail \ No newline at end of file diff --git a/helpers/wallet.py b/helpers/wallet.py index 3467ed1..f7a1e19 100644 --- a/helpers/wallet.py +++ b/helpers/wallet.py @@ -207,28 +207,30 @@ def verify_sp_output( def build_transaction( - spend_key_hex: str, - recipient: str, - amount: int, - fee_rate: float, - utxos: list[dict], - network: str = "Mainnet", + spend_key_hex: str, + scan_secret_hex: str, + recipient: str, + amount: int, + fee_rate: float, + utxos: list[dict], + network: str = "Mainnet", ) -> dict: """ Build and sign a Bitcoin transaction. Supports Silent Payment addresses (sp1/tsp1) and standard on-chain addresses. + Change goes to the wallet's own m=1 labeled SP address (BIP-352 reserved + change index), producing a unique scriptPubKey only the wallet's scanner + can recognize as its own. Returns dict with tx_hex, fee, amount, change. """ - # # ── 1. Parse spend key ──────────────────────────────────────────── + # ── 1. Parse spend key ──────────────────────────────────────────────── spend_key = ec.PrivateKey(bytes.fromhex(spend_key_hex)) - n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - # ── 2. Build per-input tweaked keys and scripts ─────────────────── - input_keys = [] + # ── 2. Build per-input tweaked keys and scripts ─────────────────────── + input_keys = [] input_scripts = [] for utxo in utxos: - # BlindBit: full_signing_key = priv_key_tweak + spend_key priv_key_tweak_hex = utxo.get("priv_key_tweak") or "" if not priv_key_tweak_hex: raise ValueError(f"Missing priv_key_tweak for utxo {utxo['txid']}") @@ -238,29 +240,24 @@ def build_transaction( raise ValueError(f"Missing pub_key for utxo {utxo['txid']}") # full_secret = priv_key_tweak + spend_key mod n - priv_tweak_int = int_from_bytes(bytes.fromhex(priv_key_tweak_hex)) - spend_key_int = int_from_bytes(spend_key.secret) + priv_tweak_int = int_from_bytes(bytes.fromhex(priv_key_tweak_hex)) + spend_key_int = int_from_bytes(spend_key.secret) full_secret_int = (priv_tweak_int + spend_key_int) % n - # derive pubkey and negate if odd y + # Derive pubkey and negate if odd y (BIP-340) full_pub_point = pubkey_point_gen_from_int(full_secret_int) if not has_even_y(full_pub_point): full_secret_int = n - full_secret_int - full_pub_point = pubkey_point_gen_from_int(full_secret_int) - - signing_key = ec.PrivateKey(full_secret_int.to_bytes(32, "big")) + full_pub_point = pubkey_point_gen_from_int(full_secret_int) - # ScriptPubKey uses pub_key from BlindBit directly (top level) - actual_x_only = bytes.fromhex(pub_key_hex) # already x-only 32 bytes + signing_key = ec.PrivateKey(full_secret_int.to_bytes(32, "big")) + actual_x_only = bytes.fromhex(pub_key_hex) # already x-only 32 bytes actual_script = Script(bytes([0x51, 0x20]) + actual_x_only) - # Verify - derived_x = ser256(full_pub_point[0]).hex() - input_keys.append(signing_key) input_scripts.append((actual_script, actual_x_only)) - # ── 3. Recipient scriptpubkey ───────────────────────────────────── + # ── 3. Recipient scriptpubkey ───────────────────────────────────────── if recipient.startswith("sp1") or recipient.startswith("tsp1"): recipient_script = Script( derive_sp_scriptpubkey(recipient, spend_key.secret, utxos) @@ -271,14 +268,13 @@ def build_transaction( except Exception as e: raise ValueError(f"Invalid recipient address: {str(e)}") - # ── 4. Calculate amounts ────────────────────────────────────────── - total_input = sum(u["amount"] for u in utxos) - # Estimate vsize: 10 base + 57.5 per taproot input + 31 per output + # ── 4. Calculate amounts ────────────────────────────────────────────── + total_input = sum(u["amount"] for u in utxos) + # Estimate vsize: 10 base + 57.5 per taproot input + 31 per output (2 outputs) estimated_vsize = int(10 + (57.5 * len(utxos)) + (31 * 2)) - # Round up to nearest sat — floor would underpay, ceil ensures broadcast - fee = max(1, math.ceil(estimated_vsize * fee_rate)) - # fee = estimated_vsize * fee_rate - change_amount = total_input - amount - fee + fee = max(1, math.ceil(estimated_vsize * fee_rate)) + change_amount = total_input - amount - fee + if change_amount < 0: raise ValueError( f"Insufficient funds. Need {amount + fee} sats " @@ -287,21 +283,46 @@ def build_transaction( # If change is below dust threshold, try two strategies: if 0 < change_amount < 546: - # Strategy 1: reduce amount to make change viable reduced_amount = amount - (546 - change_amount) if reduced_amount >= 546: + # Strategy 1: reduce amount to make change viable change_amount = total_input - reduced_amount - fee - amount = reduced_amount + amount = reduced_amount logger.debug( f"Adjusted amount to {amount} sats to avoid dust change " f"— change now {change_amount} sats" ) else: - # Strategy 2: add dust to fee — can't reduce amount further + # Strategy 2: absorb dust into fee logger.debug(f"Change {change_amount} sats below dust — adding to fee") - fee += change_amount + fee += change_amount change_amount = 0 - # ── 5. Build inputs ─────────────────────────────────────────────────── + + # ── 5. Derive BIP-352 change scriptpubkey (m=1) ────────────────────── + # Per BIP-352 spec, change MUST go to the wallet's own m=1 labeled SP + # address — never back to m=0 (the public sp1… address). This produces + # a unique scriptPubKey only this wallet's scanner can identify. + change_script = None + if change_amount >= 546: + spend_pub_hex = coincurve.PublicKey.from_secret( + spend_key.secret + ).format(compressed=True).hex() + + hrp = "sp" if network.lower() == "mainnet" else "tsp" + change_sp_address = generate_labeled_sp_address( + scan_secret_hex = scan_secret_hex, + spend_pub_hex = spend_pub_hex, + m = 1, # BIP-352 change label + hrp = hrp, + ) + + # Treat the m=1 address as a regular SP recipient — same code path + # as for any external sp1… recipient, but the "recipient" is ourself + change_script = Script( + derive_sp_scriptpubkey(change_sp_address, spend_key.secret, utxos) + ) + + # ── 6. Build inputs (BIP69 sorted) ──────────────────────────────────── tx_inputs_with_keys = [ ( TransactionInput(bytes.fromhex(u["txid"]), int(u.get("vout", 0))), @@ -311,23 +332,18 @@ def build_transaction( ) for i, u in enumerate(utxos) ] - - # BIP69 sort tx_inputs_with_keys.sort(key=lambda x: (x[0].txid.hex(), x[0].vout)) - tx_inputs = [t[0] for t in tx_inputs_with_keys] - input_keys_sorted = [t[1] for t in tx_inputs_with_keys] + tx_inputs = [t[0] for t in tx_inputs_with_keys] + input_keys_sorted = [t[1] for t in tx_inputs_with_keys] input_scripts_sorted = [t[2] for t in tx_inputs_with_keys] input_amounts_sorted = [t[3] for t in tx_inputs_with_keys] - # ── 6. Build outputs ────────────────────────────────────────────────── + # ── 7. Build outputs (BIP69 sorted) ─────────────────────────────────── tx_outputs = [TransactionOutput(amount, recipient_script)] - - if change_amount >= 546: - change_script = input_scripts_sorted[0][0] + if change_script is not None: tx_outputs.append(TransactionOutput(change_amount, change_script)) - # BIP69: sort outputs by value then scriptpubkey tx_outputs.sort( key=lambda x: ( x.value, @@ -337,16 +353,22 @@ def build_transaction( ) ) - # ── 6b. Verify SP output is in tx before signing ────────────────────── + # ── 7b. Verify SP outputs are present before signing ───────────────── if recipient.startswith("sp1") or recipient.startswith("tsp1"): if not verify_sp_output(recipient_script, tx_outputs): raise ValueError( - f"Derived SP output not found in transaction outputs. " - f"Funds would be unrecoverable. Aborting." + "Derived SP recipient output not found in transaction outputs. " + "Funds would be unrecoverable. Aborting." + ) + if change_script is not None: + if not verify_sp_output(change_script, tx_outputs): + raise ValueError( + "Derived SP change output not found in transaction outputs. " + "Change would be unrecoverable. Aborting." ) - # ── 7. Construct PSBT ───────────────────────────────────────────────── - tx = Transaction(vin=tx_inputs, vout=tx_outputs) + # ── 8. Construct PSBT ───────────────────────────────────────────────── + tx = Transaction(vin=tx_inputs, vout=tx_outputs) psbt = PSBT(tx) for i in range(len(tx_inputs)): @@ -355,27 +377,24 @@ def build_transaction( input_amounts_sorted[i], input_scripts_sorted[i][0] ) - # ── 8. Collect sighash inputs ───────────────────────────────────────── - utxo_amounts = [inp.witness_utxo.value for inp in psbt.inputs] + # ── 9. Sign each input ─────────────────────────────────────────────── + utxo_amounts = [inp.witness_utxo.value for inp in psbt.inputs] utxo_scripts = [inp.witness_utxo.script_pubkey for inp in psbt.inputs] - # ── 9. Sign each input with sorted keys ────────────────────────────── for i in range(len(psbt.inputs)): - h = taproot_sighash(tx, i, utxo_scripts, utxo_amounts, sighash_type=0) - priv_bytes = input_keys_sorted[i].secret # ← use sorted keys - cc_key = coincurve.PrivateKey(priv_bytes) + h = taproot_sighash(tx, i, utxo_scripts, utxo_amounts, sighash_type=0) + priv_bytes = input_keys_sorted[i].secret + cc_key = coincurve.PrivateKey(priv_bytes) sig_bytes = cc_key.sign_schnorr(h) sig_bytes = sig_bytes.rjust(64, b"\x00") psbt.inputs[i].taproot_key_sig = SchnorrSig.parse(sig_bytes) - # ── 10. Finalize manually ────────────────────────────────────────────── + # ── 10. Finalize and extract ───────────────────────────────────────── for inp in psbt.inputs: if inp.taproot_key_sig is not None: inp.final_scriptwitness = Witness([inp.taproot_key_sig.serialize()]) - inp.final_scriptsig = Script(b"") + inp.final_scriptsig = Script(b"") - # ── 10. Extract ─────────────────────────────────────────────────────── - # Copy witnesses into the transaction for i, inp in enumerate(psbt.inputs): if inp.final_scriptwitness: tx.vin[i].witness = inp.final_scriptwitness @@ -383,14 +402,14 @@ def build_transaction( tx_hex = tx.serialize().hex() return { - "tx_hex": tx_hex, - "fee": fee, - "amount": amount, - "change": change_amount, - "total_input": total_input, - "recipient": recipient, + "tx_hex": tx_hex, + "fee": fee, + "amount": amount, + "change": change_amount, + "total_input": total_input, + "recipient": recipient, "fee_rate_used": fee_rate, - "vsize": estimated_vsize, + "vsize": estimated_vsize, } @@ -498,10 +517,29 @@ def generate_labeled_sp_address( scan_secret_hex: str, spend_pub_hex: str, m: int, hrp: str = "sp" ) -> str: """ - Derive a BIP352 labeled Silent Payment address. - B_m = B_spend + TaggedHash("BIP0352/Label", b_scan || ser32(m)) * G - m=0 is reserved for change, user labels start at m=1 + Derive a BIP-352 LABELED Silent Payment address. + + B_m = B_spend + TaggedHash("BIP0352/Label", b_scan || ser32(m)) * G + + Reserved indices (per BIP-352 spec): + - m=0 → default address (NO tweak applied; computed elsewhere from + B_spend directly — do NOT call this function with m=0) + - m=1 → change label (reserved for self-send change outputs) + - m≥2 → user-defined labels + + Args: + scan_secret_hex: receiver's scan private key (hex) + spend_pub_hex: receiver's spend public key (33-byte compressed, hex) + m: label index (must be ≥ 1) + hrp: "sp" for mainnet, "tsp" for testnet/signet """ + if not isinstance(m, int): + raise TypeError(f"label_index (m) must be an integer, got {type(m).__name__}") + if m < 1: + raise ValueError( + f"label_index must be ≥ 1 (m=0 is the default address — use a " + f"separate derivation; got m={m})" + ) scan_secret_bytes = bytes.fromhex(scan_secret_hex) spend_pub_bytes = bytes.fromhex(spend_pub_hex) diff --git a/migrations.py b/migrations.py index 91d06c6..1e28b8d 100644 --- a/migrations.py +++ b/migrations.py @@ -31,6 +31,11 @@ async def m001_initial(db): utxo_state TEXT NOT NULL, timestamp INTEGER NOT NULL DEFAULT 0, wallet_id TEXT NOT NULL, + label TEXT DEFAULT NULL, + frozen BOOLEAN DEFAULT FALSE, + freeze_reason TEXT DEFAULT NULL, + suspected_dust BOOLEAN DEFAULT FALSE, + spent_in_txid TEXT DEFAULT NULL, label_index INTEGER ); """ @@ -55,8 +60,46 @@ async def m002_subaccounts(db): CREATE TABLE IF NOT EXISTS silnt.wallet_addresses ( sp_address TEXT PRIMARY KEY, id TEXT NOT NULL, - wallet_id TEXT NOT NULL, + wallet_id TEXT NOT NULL, + label TEXT DEFAULT NULL, label_index INTEGER NOT NULL, created_at INTEGER NOT NULL DEFAULT 0 ) """) + + +async def m003_add_spent_in_txid(db): + await db.execute( + "CREATE INDEX IF NOT EXISTS utxos_spent_in_txid ON silnt.utxos(spent_in_txid)" + ) + +async def m004_add_spent_at(db): + await db.execute( + "ALTER TABLE silnt.utxos ADD COLUMN IF NOT EXISTS spent_at INTEGER DEFAULT NULL" + ) + await db.execute( + "CREATE INDEX IF NOT EXISTS utxos_spent_at ON silnt.utxos(spent_at)" + ) + await db.execute( + "CREATE INDEX IF NOT EXISTS utxos_wallet_timestamp ON silnt.utxos(wallet_id, timestamp)" + ) + +async def m005_trusted_devices(db): + await db.execute( + """ + CREATE TABLE IF NOT EXISTS silnt.trusted_devices ( + id TEXT PRIMARY KEY, + user_id TEXT NOT NULL, + device_id TEXT NOT NULL, + user_agent TEXT, + ip TEXT, + label TEXT, + confirmed_at INTEGER NOT NULL, + last_seen_at INTEGER NOT NULL, + UNIQUE(user_id, device_id) + ) + """ + ) + await db.execute( + "CREATE INDEX IF NOT EXISTS trusted_devices_user ON silnt.trusted_devices(user_id)" + ) \ No newline at end of file diff --git a/models.py b/models.py index aeb7457..8b34683 100644 --- a/models.py +++ b/models.py @@ -1,5 +1,4 @@ -from typing import Optional - +from typing import Optional, List from fastapi import Query from pydantic import BaseModel @@ -9,6 +8,7 @@ class BlindbitConfig(BaseModel): mempool_url: str = "https://mempool.space" min_scan_height: int = 0 # 0 = no minimum; e.g. 840000 = no scans before block 840000 max_wallets_per_user: int = 0 # 0 = unlimited + dust_threshold_sats: int = 5000 class CreateWallet(BaseModel): mnemonic: str = None @@ -40,7 +40,11 @@ class UTXORecord(BaseModel): utxo_state: str timestamp: int wallet_id: str + label: Optional[str] = None # individual utxo user created label label_index: Optional[int] = None # None = main wallet, int = subaccount + frozen: bool = False + freeze_reason: Optional[str] + suspected_dust: bool = False class ScanWalletRequest(BaseModel): @@ -50,20 +54,30 @@ class ScanWalletRequest(BaseModel): spend_key: str +class UtxoForTx(BaseModel): + txid: str + vout: int = 0 + amount: int + priv_key_tweak: str + pub_key: str + label: Optional[str] = None + class BuildTxRequest(BaseModel): wallet_id: str recipient: str amount: int fee_rate: float = 1 memo: str = "" - utxos: list[dict] = [] + utxos: list[dict] spend_key: str + scan_secret: str class BroadcastTxRequest(BaseModel): tx_hex: str wallet_id: Optional[str] = None spent_txids: list[str] = [] + spent_outpoints: list[tuple[str, int]] = [] # list of [txid, vout] class RecoverKeysRequest(BaseModel): @@ -83,15 +97,16 @@ class WalletAddress(BaseModel): created_at: int = 0 -class PreviewAddressRequest(BaseModel): - label_index: int +class PreviewAddressRequest(BaseModel): scan_secret: str spend_key: str + label_index: Optional[int] = None # auto-picked if None class SaveAddressRequest(BaseModel): sp_address: str - label_index: int + label: Optional[str] = None + label_index: Optional[int] = None class CloudflareConfig(BaseModel): @@ -105,4 +120,40 @@ class SetupBip353Request(BaseModel): ttl: int = 300 # DNS TTL in seconds class ForgotPasswordRequest(BaseModel): - email: str \ No newline at end of file + email: str + +class UpdateUtxoLabel(BaseModel): + label: str = '' + +class UpdateUtxoFrozenRequest(BaseModel): + frozen: bool + +class UpdateAddressLabelRequest(BaseModel): + label: Optional[str] = None + +class TrustedDevice(BaseModel): + id: str + user_id: str + device_id: str + user_agent: Optional[str] = None + ip: Optional[str] = None + label: Optional[str] = None + confirmed_at: int + last_seen_at: int + + +class DeviceCheckResponse(BaseModel): + status: str # 'trusted' | 'pending' + device_count: int + cap: int + + +class DeviceConfirmResponse(BaseModel): + confirmed: bool + device_count: int + cap: int + +class DeviceListResponse(BaseModel): + devices: List[TrustedDevice] + current_device: Optional[str] = None + cap: int \ No newline at end of file diff --git a/static/components/utxo-list.js b/static/components/utxo-list.js index 92c4a9b..b317311 100644 --- a/static/components/utxo-list.js +++ b/static/components/utxo-list.js @@ -49,7 +49,14 @@ window.app.component('utxo-list', { field: 'timestamp', sortable: true, sort: (a, b) => a - b - } + }, + { + name: 'label', + align: 'left', + label: 'Label', + field: 'label', + sortable: false + }, ], pagination: { rowsPerPage: 10 @@ -133,6 +140,35 @@ window.app.component('utxo-list', { this.utxoSelectAmount = this.payedAmount this.applyUtxoSelectionMode() }, + startEditLabel: function (utxo) { + utxo.editingLabel = true + utxo.labelDraft = utxo.label || '' + }, + + cancelEditLabel: function (utxo) { + utxo.editingLabel = false + utxo.labelDraft = '' + }, + + saveLabel: async function (utxo) { + try { + await LNbits.api.request( + 'PUT', + `/siLNt/api/v1/utxos/${utxo.txid}/label`, + this.g.user.wallets[0].inkey, + { label: utxo.labelDraft || '' } + ) + utxo.label = utxo.labelDraft || '' + utxo.editingLabel = false + Quasar.Notify.create({ + type: 'positive', + message: utxo.label ? `Label set: ${utxo.label}` : 'Label cleared.', + timeout: 3000 + }) + } catch (error) { + LNbits.utils.notifyApiError(error) + } + }, applyUtxoSelectionMode: function () { const mode = this.utxoSelectionMode const isSelectAll = mode === 'Select All' diff --git a/static/components/wallet-list.js b/static/components/wallet-list.js index 5808c65..1b70fd2 100644 --- a/static/components/wallet-list.js +++ b/static/components/wallet-list.js @@ -14,6 +14,7 @@ window.app.component('wallet-list', { emits: ['accounts-update', 'fetch-utxos', 'scan-wallet', 'clear-utxos', 'open-bip353', 'send-wallet'], data: function () { return { + thrillaUrl: 'https://signet.thrilla.me', // or pull from server config walletAccounts: [], address: {}, formDialog: { @@ -150,17 +151,53 @@ window.app.component('wallet-list', { this.inkey, data ) - this.walletAccounts.push(mapWalletAccount(response.data)) - this.formDialog.show = false + const r = response.data || {} - await this.refreshWalletAccounts() - Quasar.Notify.create({ - type: 'positive', - message: 'Silent Payment Wallet Added.' - }) - } catch (error) { - LNbits.utils.notifyApiError(error) - } + this.formDialog.show = false + await this.refreshWalletAccounts() + + // If keys were returned, show a one-time copy dialog + if (r.scan_secret && r.spend_key) { + const keysJson = JSON.stringify({ + wallet_id: r.wallet_id, + scan_secret: r.scan_secret, + spend_key: r.spend_key, + }, null, 2) + + Quasar.Dialog.create({ + title: 'Wallet Keys — Save These Now', + message: + 'Your wallet has been created. The keys below are shown ONCE and ' + + 'will NOT be stored on the server.\\n\\n' + + 'To use this wallet, open the Thrilla app, recover the wallet ' + + 'with your mnemonic, or paste these keys directly.\\n\\n' + + 'If you lose them, you\'ll need to re-import from the mnemonic.', + html: false, + message: `
${keysJson}
`, + ok: { + label: 'I have saved them', + color: 'positive', + }, + persistent: true, + }) + + Quasar.copyToClipboard(keysJson) + this.$q.notify({ + type: 'positive', + message: 'Wallet keys copied to clipboard. Save them somewhere safe.', + timeout: 10000, + }) + } else { + this.$q.notify({ + type: 'positive', + message: 'Silent Payment Wallet created.', + timeout: 5000, + }) + } + } catch (error) { + LNbits.utils.notifyApiError(error) + } }, updateWalletDialog(walletAccountId) { var wallet = _.findWhere(this.walletAccounts, {id: walletAccountId}) @@ -328,37 +365,17 @@ window.app.component('wallet-list', { } }, generateAddress: async function (wallet) { - const rw = this.walletAccounts.find(w => w.id === wallet.id) - if (!rw) return - - if ((rw.addresses || []).length >= 10) { - this.$q.notify({ type: 'warning', message: 'Maximum of 10 labeled addresses per wallet reached.', timeout: 5000 }) - return - } - - const currentAddresses = rw.addresses || [] - const existingMax = currentAddresses.reduce((max, a) => Math.max(max, a.label_index || 0), 0) - const nextIndex = existingMax + 1 - - try { - const {data} = await LNbits.api.request( - 'POST', - `/siLNt/api/v1/wallet/${rw.id}/addresses/preview`, - this.inkey, - { label_index: nextIndex } - ) - rw.addresses = [...currentAddresses, { - _tempId: Date.now(), - id: null, - wallet_id: rw.id, - sp_address: data.sp_address, - label_index: nextIndex, - saved: false - }] - this.$emit('addresses-changed') - } catch (error) { - LNbits.utils.notifyApiError(error) - } + this.$q.notify({ + type: 'info', + message: 'Open this wallet in the Thrilla app to generate a labeled address.', + caption: 'LNbits doesn\'t store wallet keys for security reasons.', + timeout: 7000, + actions: [{ + label: 'Open Thrilla', + color: 'white', + handler: () => window.open(this.thrillaUrl, '_blank'), + }], + }) }, saveAddress: async function (wallet, addr) { diff --git a/static/js/index.js b/static/js/index.js index 8e39368..4358670 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -82,7 +82,18 @@ window.app = Vue.createApp({ } catch (e) { return 'https://mempool.space' } - } + }, + selectedUtxoLabels: function () { + if (!this.sendUtxos || !this.sendUtxos.length) return [] + const labels = [ + ...new Set( + this.sendUtxos + .filter(u => u.selected && u.label) + .map(u => u.label) + ) + ] + return labels +}, }, methods: { @@ -104,7 +115,9 @@ window.app = Vue.createApp({ label: u.label, priv_key_tweak: u.priv_key_tweak, pub_key: u.pub_key, - wallet: wallet.id + wallet: wallet.id, + editingLabel: false, // ← UI state + labelDraft: '' // ← UI state })) this.utxos.data = mappedUtxos @@ -324,7 +337,7 @@ window.app = Vue.createApp({ // Load unspent UTXOs for this wallet this.sendUtxos = (this.utxos.data || []) .filter(u => u.utxo_state === 'unspent' && u.wallet === wallet.id) - .map(u => ({ ...u, selected: false })) + .map(u => ({ ...u, selected: false, label: u.label || '' })) this.showSendDialog = true }, diff --git a/templates/silnt/components/utxo-list.html b/templates/silnt/components/utxo-list.html index eae3b43..59d99d6 100644 --- a/templates/silnt/components/utxo-list.html +++ b/templates/silnt/components/utxo-list.html @@ -120,6 +120,41 @@
N/A
+ + + + Click to edit label + + + Add label + +
+ + + +
+
diff --git a/templates/silnt/components/wallet-list.html b/templates/silnt/components/wallet-list.html index 701cc05..6ec8791 100644 --- a/templates/silnt/components/wallet-list.html +++ b/templates/silnt/components/wallet-list.html @@ -1,5 +1,23 @@ + + + Wallet operations (scan, send, generate labeled addresses) are available + in the Thrilla mobile/web app, where keys are stored + securely on your device. + +
- - Send + + + Sending requires client-side keys. Use the Thrilla app on this wallet. + Load UTXOs from DB - - Scan Blockchain + + + Scanning requires client-side keys. Use the Thrilla app on this wallet. + Deleting wallet will also delete all UTXOs - - Generate SP Address + + + Address generation requires client-side keys. Use the Thrilla app. + diff --git a/templates/silnt/index.html b/templates/silnt/index.html index c203ebd..e3d4448 100644 --- a/templates/silnt/index.html +++ b/templates/silnt/index.html @@ -177,12 +177,25 @@
Send Payment
- - + + + + + + +
- + + Warning: selected UTXOs have different labels (). + Mixing labeled UTXOs may reduce privacy. +
Selected total: diff --git a/views_api.py b/views_api.py index 0a0ab16..456af04 100644 --- a/views_api.py +++ b/views_api.py @@ -4,6 +4,8 @@ import httpx import hashlib import re +import secrets +import time from .helpers.wallet import ( generate_silent_wallet_address, decrypt_mnemonic, @@ -13,10 +15,11 @@ ) from .helpers.scan import scan_wallet, get_scan_progress, request_scan_stop from .helpers.address_resolver import bip353_resolve -from fastapi import APIRouter, Depends, HTTPException, Query, Request +from fastapi import APIRouter, Depends, HTTPException, Query, Request, Response, Cookie from lnbits.core.models import WalletTypeInfo from lnbits.decorators import require_admin_key, require_invoice_key from lnbits.helpers import urlsafe_short_hash +from lnbits.settings import settings as lnbits_settings from loguru import logger from typing import Optional from .helpers.bip353_cloudflare import ( @@ -32,6 +35,19 @@ ) from .helpers.scan_rate_limiter import check_scan_allowed, mark_scan_finished from .helpers.forgot_password import request_password_reset +from .helpers.transactions import get_wallet_transaction_detail, list_wallet_transactions +from lnbits.core.crud import get_account +from lnbits.core.services.notifications import send_email_notification +from .helpers.device_auth import ( + require_trusted_device, + require_trusted_device_admin, + make_device_confirm_token, + verify_device_confirm_token, + set_device_cookie, + get_client_ip, + DEVICE_COOKIE_NAME, + MAX_TRUSTED_DEVICES_PER_USER +) from .crud import ( get_silnt_wallets, create_silnt_wallet, @@ -49,6 +65,7 @@ get_utxos_for_wallet, insert_utxos_for_wallet, update_unconfirmed_utxo, + save_wallet_address, get_wallet_addresses, count_wallet_addresses, insert_wallet_address, @@ -56,7 +73,27 @@ delete_wallet_label_addresses, get_cloudflare_config, update_cloudflare_config, - count_silnt_wallets + count_silnt_wallets, + address_exists, + update_utxo_label_by_txid, + get_utxos_by_txid, + get_next_label_index, + label_index_taken, + owner_check_dust, + update_utxo_frozen, + get_eligible_utxos, + update_address_label, + get_wallet_address, + mark_utxos_spent_by_tx, + set_utxo_freeze_manual, + clear_utxo_freeze_manual, + count_trusted_devices, + list_trusted_devices, + add_trusted_device, + get_trusted_device, + touch_trusted_device, + revoke_trusted_device, + revoke_all_other_devices ) from .models import ( @@ -72,11 +109,18 @@ CloudflareConfig, SetupBip353Request, RecoverKeysRequest, - ForgotPasswordRequest + ForgotPasswordRequest, + UpdateUtxoLabel, + UpdateUtxoFrozenRequest, + UpdateAddressLabelRequest, + TrustedDevice, + DeviceCheckResponse, + DeviceConfirmResponse, + DeviceListResponse ) MAX_ADDRESSES_PER_WALLET = 10 - +BIP352_CHANGE_LABEL_INDEX = 1 silnt_api_router = APIRouter() @@ -86,13 +130,13 @@ @silnt_api_router.get("/api/v1/wallet", status_code=HTTPStatus.OK) async def api_wallets_retrieve( network: Optional[str] = Query(None), - key_info: WalletTypeInfo = Depends(require_invoice_key), + key_info: WalletTypeInfo = Depends(require_trusted_device), ) -> list[WalletAccount]: return await get_silnt_wallets(key_info.wallet.user, network) @silnt_api_router.get( - "/api/v1/wallet/{wallet_id}", dependencies=[Depends(require_invoice_key)] + "/api/v1/wallet/{wallet_id}", dependencies=[Depends(require_trusted_device)] ) async def api_wallet_retrieve(wallet_id: str) -> WalletAccount: silnt_wallet = await get_silnt_wallet(wallet_id) @@ -105,7 +149,7 @@ async def api_wallet_retrieve(wallet_id: str) -> WalletAccount: @silnt_api_router.post("/api/v1/wallet", status_code=HTTPStatus.OK) async def api_wallet_create( - data: CreateWallet, key_info: WalletTypeInfo = Depends(require_invoice_key) + data: CreateWallet, key_info: WalletTypeInfo = Depends(require_trusted_device) ) -> dict: try: wallet_id = urlsafe_short_hash() @@ -199,7 +243,7 @@ async def api_wallet_create( async def api_wallet_update( wallet_id: str, data: CreateWallet, - key_info: WalletTypeInfo = Depends(require_invoice_key), + key_info: WalletTypeInfo = Depends(require_trusted_device), ) -> dict: try: wallet = await get_silnt_wallet(wallet_id) @@ -240,7 +284,7 @@ async def api_wallet_update( @silnt_api_router.delete( - "/api/v1/wallet/{wallet_id}", dependencies=[Depends(require_invoice_key)] + "/api/v1/wallet/{wallet_id}", dependencies=[Depends(require_trusted_device)] ) async def api_wallet_delete(wallet_id: str): wallet = await get_silnt_wallet(wallet_id) @@ -256,7 +300,7 @@ async def api_wallet_delete(wallet_id: str): @silnt_api_router.get("/api/v1/wallet/{wallet_id}/addresses") async def api_get_wallet_addresses( - wallet_id: str, key_info: WalletTypeInfo = Depends(require_invoice_key) + wallet_id: str, key_info: WalletTypeInfo = Depends(require_trusted_device) ): wallet = await get_silnt_wallet(wallet_id) if not wallet: @@ -273,7 +317,7 @@ async def api_get_wallet_addresses( async def api_preview_wallet_address( wallet_id: str, data: PreviewAddressRequest, - key_info: WalletTypeInfo = Depends(require_invoice_key), + key_info: WalletTypeInfo = Depends(require_trusted_device), ): wallet = await get_silnt_wallet(wallet_id) if not wallet: @@ -283,6 +327,14 @@ async def api_preview_wallet_address( if wallet.user != key_info.wallet.user: raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + label_index = data.label_index + if label_index is None or label_index <= 0: + label_index = await get_next_label_index(wallet_id) + elif label_index == BIP352_CHANGE_LABEL_INDEX: + # m=1 is reserved per BIP-352 — silently bump to next free + label_index = await get_next_label_index(wallet_id) + elif await label_index_taken(wallet_id, label_index): + label_index = await get_next_label_index(wallet_id) spend_pub_hex = get_spend_pub_from_secret(data.spend_key) hrp = "sp" if wallet.network == "mainnet" else "tsp" @@ -290,7 +342,7 @@ async def api_preview_wallet_address( sp_address = generate_labeled_sp_address( scan_secret_hex=data.scan_secret, spend_pub_hex=spend_pub_hex, - m=data.label_index, + m=label_index, hrp=hrp, ) except Exception as e: @@ -298,11 +350,9 @@ async def api_preview_wallet_address( status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=f"Failed to generate address: {str(e)}", ) - return { - "sp_address": sp_address, - "label_index": data.label_index, - "wallet_id": wallet_id, + "sp_address": sp_address, + "label_index": label_index, } @@ -310,7 +360,7 @@ async def api_preview_wallet_address( async def api_delete_wallet_address( wallet_id: str, address_id: str, - key_info: WalletTypeInfo = Depends(require_invoice_key), + key_info: WalletTypeInfo = Depends(require_trusted_device), ): wallet = await get_silnt_wallet(wallet_id) if not wallet: @@ -327,7 +377,7 @@ async def api_delete_wallet_address( async def api_save_generated_wallet_address( wallet_id: str, data: SaveAddressRequest, - key_info: WalletTypeInfo = Depends(require_invoice_key), + key_info: WalletTypeInfo = Depends(require_trusted_device), ): wallet = await get_silnt_wallet(wallet_id) if not wallet: @@ -343,19 +393,40 @@ async def api_save_generated_wallet_address( status_code=HTTPStatus.BAD_REQUEST, detail=f"Maximum of {MAX_ADDRESSES_PER_WALLET} addresses per wallet reached.", ) - addr_id = urlsafe_short_hash() - await insert_wallet_address(wallet_id, data.sp_address, data.label_index, addr_id) - return { - "sp_address": data.sp_address, - "label_index": data.label_index, - "wallet_id": wallet_id, - "id": addr_id, - } + if await address_exists(wallet_id, data.sp_address): + raise HTTPException( + status_code=HTTPStatus.CONFLICT, + detail="This address is already saved on this wallet. Generate a new one.", + ) + # Determine the label_index — trust server, not stale client state + label_index = data.label_index + if label_index is None or label_index <= 0: + label_index = await get_next_label_index(wallet_id) + elif await label_index_taken(wallet_id, label_index): + # Bump to next free instead of erroring + label_index = await get_next_label_index(wallet_id) + if label_index == BIP352_CHANGE_LABEL_INDEX: + # m=1 is reserved for change — bump to next free + label_index = await get_next_label_index(wallet_id) + + try: + return await save_wallet_address( + wallet_id = wallet_id, + sp_address = data.sp_address, + label = data.label, + label_index = label_index, + ) + except Exception as e: + logger.error(f"save_wallet_address failed: {e}") + raise HTTPException( + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + detail="Could not save labeled address. Please contact your administrator.", + ) @silnt_api_router.get( "/api/v1/oracle/tip", - dependencies=[Depends(require_invoice_key)], + dependencies=[Depends(require_trusted_device)], ) async def api_get_chain_tip(): blindbit = await get_blindbit_config() @@ -384,7 +455,7 @@ async def api_get_chain_tip(): @silnt_api_router.get("/api/v1/blindbit/config") async def api_get_blindbit_config( - key_info: WalletTypeInfo = Depends(require_invoice_key), + key_info: WalletTypeInfo = Depends(require_trusted_device), ) -> BlindbitConfig: """Any authenticated user can read the blindbit endpoint (needed to trigger scan). Credentials (user/pass) are included so the scan proxy can use them server-side.""" @@ -393,7 +464,7 @@ async def api_get_blindbit_config( @silnt_api_router.put("/api/v1/blindbit/config") async def api_update_blindbit_config( - data: BlindbitConfig, key_info: WalletTypeInfo = Depends(require_admin_key) + data: BlindbitConfig, key_info: WalletTypeInfo = Depends(require_trusted_device_admin) ) -> BlindbitConfig: """Only admin can write blindbit connection settings.""" return await update_blindbit_config(data) @@ -405,10 +476,10 @@ async def api_update_blindbit_config( @silnt_api_router.get( "/api/v1/utxos", description="Fetch UTXOs from blindbit", - dependencies=[Depends(require_invoice_key)], + dependencies=[Depends(require_trusted_device)], ) async def api_get_utxos( - wallet_id: str = Query(...), key_info: WalletTypeInfo = Depends(require_invoice_key) + wallet_id: str = Query(...), key_info: WalletTypeInfo = Depends(require_trusted_device) ): wallet = await get_silnt_wallet(wallet_id) if not wallet: @@ -425,7 +496,8 @@ async def api_get_utxos( async def api_scan_wallet( wallet_id: str, data: ScanWalletRequest, - key_info: WalletTypeInfo = Depends(require_invoice_key), + request: Request, + key_info: WalletTypeInfo = Depends(require_trusted_device), ): wallet = await get_silnt_wallet(wallet_id) if not wallet: @@ -476,9 +548,22 @@ async def api_scan_wallet( return result except ValueError as e: raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, detail=str(e)) + except RuntimeError as e: + # Our scan code raises RuntimeError with user-friendly messages — + # surface those without leaking implementation details + logger.error(f"Scan runtime error for {wallet_id}: {e}") + raise HTTPException( + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + detail=str(e), + ) except Exception as e: - logger.error(f"Scan failed: {e}") - raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)) + # Catch-all for unexpected errors — generic message to the user, + # full traceback in server logs + logger.error(f"Scan unexpected error for {wallet_id}: {e}", exc_info=True) + raise HTTPException( + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + detail="An unexpected error occurred during scanning. Please contact your administrator.", + ) finally: # ALWAYS release the concurrent-scan slot, even on error/exception @@ -486,7 +571,7 @@ async def api_scan_wallet( @silnt_api_router.post("/api/v1/wallet/{wallet_id}/scan/stop") async def api_stop_scan( - wallet_id: str, key_info: WalletTypeInfo = Depends(require_invoice_key) + wallet_id: str, key_info: WalletTypeInfo = Depends(require_trusted_device) ): wallet = await get_silnt_wallet(wallet_id) if not wallet: @@ -507,15 +592,15 @@ async def api_resolve_bip353( address: str = Query( ..., description="BIP353 address in email format, e.g. alice@domain.com" ), - key_info: WalletTypeInfo = Depends(require_invoice_key), + key_info: WalletTypeInfo = Depends(require_trusted_device), ) -> dict: return bip353_resolve(address=address) # Transactions -@silnt_api_router.post("/api/v1/tx/build", dependencies=[Depends(require_admin_key)]) +@silnt_api_router.post("/api/v1/tx/build", dependencies=[Depends(require_trusted_device_admin)]) async def api_build_transaction( - data: BuildTxRequest, key_info: WalletTypeInfo = Depends(require_admin_key) + data: BuildTxRequest, key_info: WalletTypeInfo = Depends(require_trusted_device_admin) ): try: wallet = await get_silnt_wallet(data.wallet_id) @@ -532,7 +617,49 @@ async def api_build_transaction( raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, detail="spend_key is required." ) + if not data.scan_secret: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail="scan_secret is required (used to derive change address).", + ) + # ── Validate UTXOs against the DB: refuse frozen, refuse non-owned ── + if not data.utxos: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail="No UTXOs provided for the transaction.", + ) + def _txid_of(u): + return u["txid"] if isinstance(u, dict) else u.txid + + def _vout_of(u): + if isinstance(u, dict): + return int(u.get("vout", 0)) + return int(getattr(u, "vout", 0) or 0) + + passed_txids_vouts = [(_txid_of(u), _vout_of(u)) for u in data.utxos] + eligible_rows = await get_eligible_utxos( + wallet_id=data.wallet_id, + txid_vout_pairs=passed_txids_vouts, + ) + eligible_set = {(r["txid"], r["vout"]) for r in eligible_rows} + + # Anything passed but not in eligible_set is either frozen, not unspent, + # or doesn't belong to this wallet + rejected = [ + (_txid_of(u), _vout_of(u)) for u in data.utxos + if (_txid_of(u), _vout_of(u)) not in eligible_set + ] + if rejected: + rejected_str = ", ".join(f"{t[:12]}…:{v}" for t, v in rejected) + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=( + f"Cannot spend these UTXOs ({rejected_str}). " + f"They are either frozen, already spent, or don't belong " + f"to this wallet. Unfreeze them or remove from selection." + ), + ) if "@" in data.recipient: user, domain = data.recipient.strip().split("@") if user and domain: @@ -544,9 +671,10 @@ async def api_build_transaction( detail="Address must resolve to Silent Payment address (sp1).", ) data.recipient = result - + result = build_transaction( spend_key_hex=data.spend_key, + scan_secret_hex = data.scan_secret, recipient=data.recipient, amount=data.amount, fee_rate=data.fee_rate, @@ -565,7 +693,7 @@ async def api_build_transaction( @silnt_api_router.post( - "/api/v1/tx/broadcast", dependencies=[Depends(require_admin_key)] + "/api/v1/tx/broadcast", dependencies=[Depends(require_trusted_device_admin)] ) async def api_broadcast_transaction(data: BroadcastTxRequest): try: @@ -590,6 +718,12 @@ async def api_broadcast_transaction(data: BroadcastTxRequest): logger.info( f"Marked {len(data.spent_txids)} UTXOs as unconfirmed_spent after broadcast of {txid}" ) + input_outpoints = [(u_txid, u_vout) for u_txid, u_vout in data.spent_outpoints] + await mark_utxos_spent_by_tx( + wallet_id=data.wallet_id, + input_outpoints=input_outpoints, + spending_txid=txid, + ) return {"txid": txid} except HTTPException: @@ -609,7 +743,7 @@ async def api_broadcast_transaction(data: BroadcastTxRequest): async def api_recover_wallet_keys( wallet_id: str, data: RecoverKeysRequest, - key_info: WalletTypeInfo = Depends(require_invoice_key), + key_info: WalletTypeInfo = Depends(require_trusted_device), ): """ Re-derive scan_secret and spend_key from mnemonic for an existing wallet. @@ -654,7 +788,7 @@ async def api_recover_wallet_keys( @silnt_api_router.get("/api/v1/config") async def api_get_config( - key_info: WalletTypeInfo = Depends(require_invoice_key), + key_info: WalletTypeInfo = Depends(require_trusted_device), ) -> dict: blindbit = await get_blindbit_config() config = Config() @@ -664,12 +798,13 @@ async def api_get_config( "sats_denominated": config.sats_denominated, "network": config.network, "min_scan_height": blindbit.min_scan_height or 0, - "wallet_count": current + "wallet_count": current, + "dust_threshold_sats": blindbit.dust_threshold_sats or 5000 } @silnt_api_router.get( "/api/v1/wallet/{wallet_id}/scan/progress", - dependencies=[Depends(require_invoice_key)], + dependencies=[Depends(require_trusted_device)], ) async def api_scan_progress(wallet_id: str): return get_scan_progress(wallet_id) @@ -678,7 +813,7 @@ async def api_scan_progress(wallet_id: str): # ── GET Cloudflare config (admin only) ─────────────────────────────────────── @silnt_api_router.get("/api/v1/cloudflare/config") async def api_get_cloudflare_config( - key_info: WalletTypeInfo = Depends(require_admin_key), + key_info: WalletTypeInfo = Depends(require_trusted_device_admin), ) -> CloudflareConfig: cf = await get_cloudflare_config() # Backfill domain if credentials are present but domain is missing @@ -696,7 +831,7 @@ async def api_get_cloudflare_config( @silnt_api_router.put("/api/v1/cloudflare/config") async def api_update_cloudflare_config( data: CloudflareConfig, - key_info: WalletTypeInfo = Depends(require_admin_key), + key_info: WalletTypeInfo = Depends(require_trusted_device_admin), ) -> CloudflareConfig: # Verify token + zone by fetching domain — also auto-populates data.domain if data.api_token and data.zone_id: @@ -717,7 +852,7 @@ async def api_update_cloudflare_config( async def api_setup_bip353( wallet_id: str, data: SetupBip353Request, - key_info: WalletTypeInfo = Depends(require_invoice_key), + key_info: WalletTypeInfo = Depends(require_trusted_device), ): wallet = await get_silnt_wallet(wallet_id) if not wallet: @@ -776,7 +911,7 @@ async def api_setup_bip353( @silnt_api_router.delete("/api/v1/wallet/{wallet_id}/bip353") async def api_delete_bip353( wallet_id: str, - key_info: WalletTypeInfo = Depends(require_invoice_key), + key_info: WalletTypeInfo = Depends(require_trusted_device), ): wallet = await get_silnt_wallet(wallet_id) if not wallet: @@ -827,4 +962,310 @@ async def api_forgot_password(data: ForgotPasswordRequest, request: Request) -> status_code=HTTPStatus.BAD_REQUEST, detail="Valid email address required.", ) - return await request_password_reset(data.email.strip().lower(), request) \ No newline at end of file + return await request_password_reset(data.email.strip().lower(), request) + +# UTXO Labels +@silnt_api_router.put("/api/v1/utxos/{txid}/label") +async def api_update_utxo_label( + txid: str, + data: UpdateUtxoLabel, + key_info: WalletTypeInfo = Depends(require_trusted_device), +): + utxos = await get_utxos_by_txid(txid) + # Find the UTXO(s) by txid and verify ownership via their parent wallet + utxos = await get_utxos_by_txid(txid) + if not utxos: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="UTXO not found.") + + # All matching UTXOs should belong to a wallet the caller owns + for utxo in utxos: + wallet = await get_silnt_wallet(utxo.wallet_id) + if not wallet or wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + + updated = await update_utxo_label_by_txid(txid, data.label) + return {"txid": txid, "label": data.label, "updated": updated} + +@silnt_api_router.put("/api/v1/wallet/{wallet_id}/addresses/{addr_id}/label") +async def api_update_address_label( + wallet_id: str, + addr_id: str, + data: UpdateAddressLabelRequest, + key_info: WalletTypeInfo = Depends(require_trusted_device), +): + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + if wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + + # Lookup the address to verify it belongs to this wallet AND grab its old label + addr = await get_wallet_address(addr_id) + if not addr: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Labeled address not found.") + if addr.wallet_id != wallet_id: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Address does not belong to this wallet.") + + new_label = (data.label or "").strip() or None + + await update_address_label(addr_id, new_label) + + return { + "id": addr_id, + "label": new_label, + "label_index": addr.label_index, + "sp_address": addr.sp_address, + } + +@silnt_api_router.put("/api/v1/utxos/{txid}/{vout}/frozen") +async def api_set_utxo_frozen( + txid: str, + vout: int, + data: UpdateUtxoFrozenRequest, + key_info: WalletTypeInfo = Depends(require_trusted_device), +): + utxos = await get_utxos_by_txid(txid) + if not utxos: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="UTXO not found.") + matching = next((u for u in utxos if u.vout == vout), None) + if not matching: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="UTXO not found at that vout.") + + wallet = await get_silnt_wallet(matching.wallet_id) + if not wallet or wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + + if data.frozen: + await set_utxo_freeze_manual(txid, vout) + else: + await clear_utxo_freeze_manual(txid, vout) + + return {"txid": txid, "vout": vout, "frozen": data.frozen} + +@silnt_api_router.get("/api/v1/wallet/{wallet_id}/transactions") +async def api_list_wallet_transactions( + wallet_id: str, + limit: int = 50, + offset: int = 0, + key_info: WalletTypeInfo = Depends(require_trusted_device), +): + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + if wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + + txs = await list_wallet_transactions(wallet_id, limit=limit, offset=offset) + return {"transactions": txs} + + +@silnt_api_router.get("/api/v1/wallet/{wallet_id}/transactions/{txid}") +async def api_get_wallet_transaction( + wallet_id: str, + txid: str, + key_info: WalletTypeInfo = Depends(require_trusted_device), +): + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist.") + if wallet.user != key_info.wallet.user: + raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Access denied.") + + return await get_wallet_transaction_detail(wallet_id, txid) + +@silnt_api_router.post("/api/v1/auth/device-check") +async def api_device_check( + request: Request, + response: Response, + key_info: WalletTypeInfo = Depends(require_invoice_key), +): + """ + Called by Thrilla after a successful login. If the device cookie is missing + or unknown, send a confirmation email and return 'pending'. Otherwise + refresh the cookie and return 'trusted'. + """ + user_id = key_info.wallet.user + cookie = request.cookies.get(DEVICE_COOKIE_NAME) + ua = request.headers.get("user-agent", "")[:512] + ip = get_client_ip(request) + + # Check if a cookie exists AND is in trusted set + if cookie: + existing = await get_trusted_device(user_id, cookie) + if existing: + # Already trusted — touch + return + await touch_trusted_device(user_id, cookie) + # Refresh cookie expiry + set_device_cookie(response, cookie) + return DeviceCheckResponse( + status = "trusted", + device_count = await count_trusted_devices(user_id), + cap = MAX_TRUSTED_DEVICES_PER_USER, + ) + + # New device — generate a fresh device_id (server-issued) + new_device_id = secrets.token_urlsafe(24) + + # Check the cap + current_count = await count_trusted_devices(user_id) + if current_count >= MAX_TRUSTED_DEVICES_PER_USER: + # Still send email — but the confirmation step will reject + # Better UX: tell the user up front + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=( + f"This account already has {MAX_TRUSTED_DEVICES_PER_USER} " + f"trusted devices (the maximum). Sign in from a trusted device " + f"and revoke one in Settings → Devices before continuing." + ), + ) + + # Look up the user's email + account = await get_account(user_id) + if not account or not account.email: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail="This account has no email address. Cannot send confirmation.", + ) + + # Build + send the confirmation email + token = make_device_confirm_token(user_id, new_device_id, ua, ip) + # NOTE: configure base URL appropriately for your deployment + base_url = "https://signet.thrilla.me" + confirm_url = f"{base_url.rstrip('/')}/confirm-device?token={token}" + + subject = "Confirm a new device on your wallet" + body = ( + f"Hi {account.username or 'there'},\n\n" + f"A new device tried to sign in to your wallet:\n\n" + f" Browser: {ua or 'unknown'}\n" + f" IP: {ip or 'unknown'}\n" + f" Time: {time.strftime('%Y-%m-%d %H:%M UTC', time.gmtime())}\n\n" + f"If this was you, confirm the device here:\n\n" + f" {confirm_url}\n\n" + f"This link expires in 1 hour.\n\n" + f"If this WASN'T you, change your password immediately and ignore this email." + ) + + res = await send_email_notification( + to_emails = [account.email], + message = body, + subject = subject, + ) + if res.get("status") != "ok": + logger.warning(f"Device confirmation email failed: {res}") + raise HTTPException( + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + detail="Could not send confirmation email. Please contact your administrator.", + ) + + # Set the cookie now — but the device won't be trusted until confirmed. + # Future requests will carry the cookie; the confirm endpoint reads it + # from the URL token (more reliable than relying on the cookie at click-time). + set_device_cookie(response, new_device_id) + + return DeviceCheckResponse( + status = "pending", + device_count = current_count, + cap = MAX_TRUSTED_DEVICES_PER_USER, + ) + + +@silnt_api_router.get("/api/v1/auth/device-confirm") +async def api_device_confirm( + request: Request, + response: Response, + token: str, +): + """ + Called when the user clicks the link in the confirmation email. + Validates the token + cap, then writes the device into trusted_devices. + Also sets the cookie (in case the user opened the link in a different + tab/window without the cookie present). + """ + payload = verify_device_confirm_token(token) + if not payload: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail="Invalid or expired confirmation token.", + ) + + user_id = payload["user_id"] + device_id = payload["device_id"] + ua = payload.get("ua", "") + ip = payload.get("ip", "") + + # Hard cap re-check at confirm time (cap may have changed since email) + current_count = await count_trusted_devices(user_id) + if current_count >= MAX_TRUSTED_DEVICES_PER_USER: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=( + f"This account already has {MAX_TRUSTED_DEVICES_PER_USER} " + f"trusted devices. Revoke one before adding another." + ), + ) + + await add_trusted_device( + user_id = user_id, + device_id = device_id, + user_agent = ua, + ip = ip, + ) + + # Ensure the cookie matches (in case user opened link in different browser) + set_device_cookie(response, device_id) + + return DeviceConfirmResponse( + confirmed = True, + device_count = current_count + 1, + cap = MAX_TRUSTED_DEVICES_PER_USER, + ) + + +@silnt_api_router.get("/api/v1/devices") +async def api_list_devices( + request: Request, + key_info: WalletTypeInfo = Depends(require_trusted_device), + silnt_device_id: Optional[str] = Cookie(default=None), +): + devices = await list_trusted_devices(key_info.wallet.user) + return DeviceListResponse( + devices = devices, + current_device = silnt_device_id, + cap = MAX_TRUSTED_DEVICES_PER_USER, + ) + + +@silnt_api_router.delete("/api/v1/devices/{device_row_id}") +async def api_revoke_device( + device_row_id: str, + request: Request, + response: Response, + key_info: WalletTypeInfo = Depends(require_trusted_device), + silnt_device_id: Optional[str] = Cookie(default=None), +): + devices = await list_trusted_devices(key_info.wallet.user) + target = next((d for d in devices if d.id == device_row_id), None) + if not target: + raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Device not found.") + + deleted = await revoke_trusted_device(key_info.wallet.user, device_row_id) + + # If user revoked the CURRENT device, clear the cookie too + if target.device_id == silnt_device_id: + response.delete_cookie(DEVICE_COOKIE_NAME, path="/") + + return {"deleted": bool(deleted), "device_row_id": device_row_id} + + +@silnt_api_router.post("/api/v1/devices/sign-out-others") +async def api_sign_out_others( + request: Request, + key_info: WalletTypeInfo = Depends(require_trusted_device), + silnt_device_id: Optional[str] = Cookie(default=None), +): + if not silnt_device_id: + raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, detail="No active device.") + removed = await revoke_all_other_devices(key_info.wallet.user, silnt_device_id) + return {"removed_count": removed} \ No newline at end of file From 5541f81d7f0428e5078ce9028f05b30a0af3cfaf Mon Sep 17 00:00:00 2001 From: Ponthief Date: Sat, 30 May 2026 22:17:23 +0100 Subject: [PATCH 59/83] add new wallet generation --- crud.py | 236 +++++++- helpers/address_resolver.py | 25 +- helpers/device_auth.py | 83 +-- helpers/dust_check.py | 11 +- helpers/transactions.py | 65 +-- helpers/user.py | 30 ++ helpers/wallet.py | 38 +- migrations.py | 39 +- models.py | 93 +++- pyproject.toml | 1 + templates/silnt/_api_docs.html | 4 +- templates/silnt/components/wallet-list.html | 18 +- templates/silnt/index.html | 10 +- uv.lock | 11 + views_api.py | 567 ++++++++++++++++---- 15 files changed, 992 insertions(+), 239 deletions(-) create mode 100644 helpers/user.py diff --git a/crud.py b/crud.py index dd29652..723acb1 100644 --- a/crud.py +++ b/crud.py @@ -12,7 +12,9 @@ WalletAddress, CloudflareConfig, UpdateUtxoLabel, - TrustedDevice + TrustedDevice, + UserPrefs, + Bip353Request ) from embit.descriptor import Descriptor, Key @@ -151,18 +153,20 @@ async def get_utxos_for_wallet(wallet_id: str) -> list[UTXORecord]: async def insert_utxos_for_wallet(wallet_id: str, utxos: list) -> None: for utxo in utxos: await db.execute( - """INSERT INTO silnt.utxos (txid, vout, amount, priv_key_tweak, pub_key, utxo_state, timestamp, wallet_id, label) - VALUES (:txid, :vout, :amount, :priv_key_tweak, :pub_key, :utxo_state, :timestamp, :wallet_id, :label) - ON CONFLICT (txid) DO UPDATE SET - amount = EXCLUDED.amount, - priv_key_tweak = EXCLUDED.priv_key_tweak, - pub_key = EXCLUDED.pub_key, - utxo_state = CASE - WHEN silnt.utxos.utxo_state IN ('spent', 'unconfirmed_spent') - THEN silnt.utxos.utxo_state - ELSE EXCLUDED.utxo_state - END, - label = COALESCE(silnt.utxos.label, EXCLUDED.label) + """INSERT INTO silnt.utxos + (txid, vout, amount, priv_key_tweak, pub_key, utxo_state, timestamp, wallet_id, label) + VALUES + (:txid, :vout, :amount, :priv_key_tweak, :pub_key, :utxo_state, :timestamp, :wallet_id, :label) + ON CONFLICT (txid, vout, wallet_id) DO UPDATE SET + amount = EXCLUDED.amount, + priv_key_tweak = EXCLUDED.priv_key_tweak, + pub_key = EXCLUDED.pub_key, + utxo_state = CASE + WHEN silnt.utxos.utxo_state IN ('spent', 'unconfirmed_spent') + THEN silnt.utxos.utxo_state + ELSE EXCLUDED.utxo_state + END, + label = COALESCE(silnt.utxos.label, EXCLUDED.label) """, utxo.to_db_row(wallet_id), ) @@ -300,7 +304,7 @@ async def count_silnt_wallets(user: str, network: Optional[str] = None) -> int: return row["c"] if row else 0 async def update_utxo_label_by_txid( - txid: str, label: Optional[str], wallet_id: Optional[str] = None + txid: str, label: Optional[str], wallet_id: Optional[str] ) -> int: """ Set or clear the label on UTXO(s) matching the given txid. @@ -512,6 +516,30 @@ async def mark_utxos_spent_by_tx( result = await db.execute(sql, params) return getattr(result, "rowcount", 0) or 0 +async def mark_utxos_spent_by_outpoints( + wallet_id: str, + outpoints: list[tuple[str, int]], # [(txid, vout), ...] + spending_txid: str, +) -> int: + if not outpoints: + return 0 + now = int(time.time()) + affected = 0 + for (in_txid, in_vout) in outpoints: + result = await db.execute( + """UPDATE silnt.utxos + SET utxo_state = 'unconfirmed_spent', + spent_in_txid = :stxid, + spent_at = :ts + WHERE wallet_id = :wid + AND txid = :txid + AND vout = :vout + AND utxo_state IN ('unspent', 'unconfirmed')""", + {"wid": wallet_id, "txid": in_txid, "vout": int(in_vout), + "stxid": spending_txid, "ts": now}, + ) + affected += getattr(result, "rowcount", 0) or 0 + return affected async def is_own_sent_tx(wallet_id: str, txid: str) -> bool: """ @@ -766,4 +794,182 @@ async def touch_trusted_device(user_id: str, device_id: str) -> None: SET last_seen_at = :ts WHERE user_id = :uid AND device_id = :did""", {"uid": user_id, "did": device_id, "ts": int(time.time())}, - ) \ No newline at end of file + ) + +async def get_user_prefs(user_id: str) -> Optional[UserPrefs]: + row = await db.fetchone( + "SELECT * FROM silnt.user_prefs WHERE user_id = :uid", + {"uid": user_id}, + ) + return UserPrefs(**dict(row)) if row else None + + +async def upsert_user_prefs( + user_id: str, + dust_threshold_sats: Optional[int], +) -> UserPrefs: + now = int(time.time()) + await db.execute( + """INSERT INTO silnt.user_prefs (user_id, dust_threshold_sats, updated_at) + VALUES (:uid, :dts, :ts) + ON CONFLICT (user_id) DO UPDATE + SET dust_threshold_sats = EXCLUDED.dust_threshold_sats, + updated_at = EXCLUDED.updated_at""", + {"uid": user_id, "dts": dust_threshold_sats, "ts": now}, + ) + return UserPrefs( + user_id = user_id, + dust_threshold_sats = dust_threshold_sats, + updated_at = now, + ) + + +async def get_effective_dust_threshold(user_id: str) -> int: + """ + Resolve the dust threshold for a user. + Priority: + 1. User's own prefs.dust_threshold_sats (if non-NULL and > 0) + 2. Admin's BlindbitConfig.dust_threshold_sats (if non-zero) + 3. Hard fallback: 5000 sats + """ + prefs = await get_user_prefs(user_id) + if prefs and prefs.dust_threshold_sats and prefs.dust_threshold_sats > 0: + return int(prefs.dust_threshold_sats) + blindbit = await get_blindbit_config() + return int(blindbit.dust_threshold_sats or 5000) + +async def create_bip353_request( + user_id: str, + wallet_id: str, + sp_address: str, + requested_username: str, + message: Optional[str], +) -> Bip353Request: + row_id = secrets.token_urlsafe(16) + now = int(time.time()) + await db.execute( + """INSERT INTO silnt.bip353_requests + (id, user_id, wallet_id, sp_address, requested_username, message, + status, created_at) + VALUES (:id, :uid, :wid, :sp, :uname, :msg, 'pending', :ts)""", + { + "id": row_id, + "uid": user_id, + "wid": wallet_id, + "sp": sp_address, + "uname": requested_username, + "msg": message, + "ts": now, + }, + ) + return Bip353Request( + id=row_id, user_id=user_id, wallet_id=wallet_id, sp_address=sp_address, + requested_username=requested_username, message=message, status="pending", + created_at=now, + ) + + +async def get_bip353_request(req_id: str) -> Optional[Bip353Request]: + row = await db.fetchone( + "SELECT * FROM silnt.bip353_requests WHERE id = :id", + {"id": req_id}, + ) + return Bip353Request(**dict(row)) if row else None + + +async def list_user_bip353_requests(user_id: str) -> List[Bip353Request]: + rows = await db.fetchall( + """SELECT * FROM silnt.bip353_requests + WHERE user_id = :uid + ORDER BY created_at DESC""", + {"uid": user_id}, + ) + return [Bip353Request(**dict(r)) for r in rows] + + +async def list_pending_bip353_requests() -> List[Bip353Request]: + rows = await db.fetchall( + """SELECT * FROM silnt.bip353_requests + WHERE status = 'pending' + ORDER BY created_at ASC""" + ) + return [Bip353Request(**dict(r)) for r in rows] + + +async def is_username_taken(username: str) -> bool: + """Check if username is already approved + active for someone.""" + row = await db.fetchone( + """SELECT 1 FROM silnt.bip353_requests + WHERE LOWER(final_username) = LOWER(:uname) + AND status = 'approved'""", + {"uname": username}, + ) + if row: + return True + # Also check the existing wallets.hr_address column (legacy addresses) + row = await db.fetchone( + """SELECT 1 FROM silnt.wallets + WHERE LOWER(hr_address) LIKE LOWER(:pat)""", + {"pat": f"{username}@%"}, + ) + return row is not None + + +async def update_bip353_request_status( + req_id: str, + status: str, + processed_by: str, + final_username: Optional[str] = None, + reject_reason: Optional[str] = None, +) -> int: + now = int(time.time()) + result = await db.execute( + """UPDATE silnt.bip353_requests + SET status = :status, + final_username = :final_username, + reject_reason = :reject_reason, + processed_at = :ts, + processed_by = :by + WHERE id = :id""", + { + "id": req_id, + "status": status, + "final_username": final_username, + "reject_reason": reject_reason, + "ts": now, + "by": processed_by, + }, + ) + return getattr(result, "rowcount", 0) or 0 + + +async def cancel_user_request(req_id: str, user_id: str) -> int: + """User cancels their own pending request.""" + result = await db.execute( + """UPDATE silnt.bip353_requests + SET status = 'cancelled', processed_at = :ts + WHERE id = :id AND user_id = :uid AND status = 'pending'""", + {"id": req_id, "uid": user_id, "ts": int(time.time())}, + ) + return getattr(result, "rowcount", 0) or 0 + +async def get_wallet_active_request(wallet_id: str) -> Optional[Bip353Request]: + """Return the currently pending request for THIS wallet, if any.""" + row = await db.fetchone( + """SELECT * FROM silnt.bip353_requests + WHERE wallet_id = :wid AND status = 'pending' + ORDER BY created_at DESC LIMIT 1""", + {"wid": wallet_id}, + ) + return Bip353Request(**dict(row)) if row else None + + +async def get_wallet_last_rejected_request(wallet_id: str) -> Optional[Bip353Request]: + """Last rejection for THIS wallet — used for per-wallet cooldown.""" + row = await db.fetchone( + """SELECT * FROM silnt.bip353_requests + WHERE wallet_id = :wid AND status = 'rejected' + ORDER BY processed_at DESC LIMIT 1""", + {"wid": wallet_id}, + ) + return Bip353Request(**dict(row)) if row else None \ No newline at end of file diff --git a/helpers/address_resolver.py b/helpers/address_resolver.py index 06f07b5..95c37b2 100644 --- a/helpers/address_resolver.py +++ b/helpers/address_resolver.py @@ -16,31 +16,19 @@ def _query_txt_with_dnssec(qname: str) -> tuple[list[str], bool]: - """ - Query a TXT record using a DNSSEC-validating resolver. - Returns (txt_records, dnssec_validated). - dnssec_validated is True only when the AD flag is set in the response, - meaning the upstream resolver successfully validated the DNSSEC chain. - Tries each resolver in DNSSEC_RESOLVERS in order. - """ qname_obj = dns.name.from_text(qname) - - # Build query with DO (DNSSEC OK) bit set so resolver includes RRSIGs request = dns.message.make_query(qname_obj, dns.rdatatype.TXT, want_dnssec=True) last_error = None for nameserver in DNSSEC_RESOLVERS: try: - # Try TCP first (more reliable for DNSSEC responses which can be large) try: response = dns.query.tcp(request, nameserver, timeout=10) except Exception: response = dns.query.udp(request, nameserver, timeout=10) - # AD flag set = resolver validated the full DNSSEC chain dnssec_valid = bool(response.flags & AD_FLAG) - # Extract TXT records from answer section records = [] for rrset in response.answer: if rrset.rdtype == dns.rdatatype.TXT: @@ -50,10 +38,21 @@ def _query_txt_with_dnssec(qname: str) -> tuple[list[str], bool]: if records: return records, dnssec_valid - # Check for NXDOMAIN (RCODE 3) + # NXDOMAIN → domain itself doesn't exist if response.rcode() == dns.rcode.NXDOMAIN: raise dns.resolver.NXDOMAIN() + # ★ NEW: resolver answered successfully (NOERROR) but there are no + # TXT records → the name has no BIP-353 record. This is a definitive + # "not found", NOT a resolver failure. Raise NoAnswer so the caller + # maps it to 404 instead of falling through to "all resolvers failed". + if response.rcode() == dns.rcode.NOERROR: + raise dns.resolver.NoAnswer(response=response) + + # Any other RCODE (SERVFAIL etc.) → try the next resolver + last_error = Exception(f"RCODE {response.rcode()} from {nameserver}") + continue + except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): raise except Exception as e: diff --git a/helpers/device_auth.py b/helpers/device_auth.py index cec60ea..6b52e22 100644 --- a/helpers/device_auth.py +++ b/helpers/device_auth.py @@ -3,6 +3,7 @@ import hashlib import json import time +import re from typing import Optional from fastapi import Cookie, Depends, HTTPException, Request, Response from http import HTTPStatus @@ -13,11 +14,43 @@ from lnbits.decorators import WalletTypeInfo, require_invoice_key from ..crud import get_trusted_device, touch_trusted_device -MAX_TRUSTED_DEVICES_PER_USER = 3 -DEVICE_COOKIE_NAME = "silnt_device_id" +MAX_TRUSTED_DEVICES_PER_USER = 5 +DEVICE_COOKIE_PREFIX = "silnt_device_id_" DEVICE_COOKIE_MAX_AGE = 365 * 24 * 3600 # 1 year DEVICE_CONFIRM_TOKEN_TTL = 3600 # 1 hour +def _is_thrilla_request(request: Request) -> bool: + # Thrilla's fetch wrapper sends this header on every call. The LNbits-native + # extension page does not. + return request.headers.get("X-Thrilla-Client") == "1" + +def _safe_user_id_for_cookie(user_id: str) -> str: + """Sanitize user_id for cookie name (allow only [a-zA-Z0-9_-]).""" + return re.sub(r"[^A-Za-z0-9_\-]", "", user_id or "")[:64] + + +def cookie_name_for_user(user_id: str) -> str: + """Per-user cookie name. Multiple users on the same browser each get + their own trust cookie.""" + return DEVICE_COOKIE_PREFIX + _safe_user_id_for_cookie(user_id) + + +def set_device_cookie(response: Response, user_id: str, device_id: str) -> None: + """Set the per-user HttpOnly device_id cookie.""" + response.set_cookie( + key = cookie_name_for_user(user_id), + value = device_id, + max_age = DEVICE_COOKIE_MAX_AGE, + httponly = True, + secure = True, + samesite = "none", + path = "/", + ) + +def clear_device_cookie(response: Response, user_id: str) -> None: + """Clear a user's device cookie (used when revoking own device).""" + response.delete_cookie(cookie_name_for_user(user_id), path="/") + def _hmac_sign(payload: str) -> str: key = (lnbits_settings.auth_secret_key or "").encode() if not key: @@ -62,19 +95,6 @@ def verify_device_confirm_token(token: str) -> Optional[dict]: return payload -def set_device_cookie(response: Response, device_id: str) -> None: - """Set the HttpOnly device_id cookie. Same-site + secure.""" - response.set_cookie( - key = DEVICE_COOKIE_NAME, - value = device_id, - max_age = DEVICE_COOKIE_MAX_AGE, - httponly = True, - secure = True, - samesite = "lax", # 'strict' breaks the email-link redirect — lax is fine - path = "/", - ) - - def get_client_ip(request: Request) -> str: """Best-effort IP extraction — checks X-Forwarded-For first (Caddy proxy).""" xff = request.headers.get("x-forwarded-for", "") @@ -86,29 +106,28 @@ def get_client_ip(request: Request) -> str: async def require_trusted_device( request: Request, key_info: WalletTypeInfo = Depends(require_invoice_key), - silnt_device_id: Optional[str] = Cookie(default=None), ) -> WalletTypeInfo: - """ - Combined dependency: validates the API key AND the device cookie. - Use this in place of `require_invoice_key` on every endpoint that should - require a trusted device. - """ - if not silnt_device_id: + + if not _is_thrilla_request(request): + return key_info + user_id = key_info.wallet.user + cookie_value = request.cookies.get(cookie_name_for_user(user_id)) + + if not cookie_value: raise HTTPException( status_code=HTTPStatus.FORBIDDEN, detail="device-not-trusted: no device cookie present", ) - device = await get_trusted_device(key_info.wallet.user, silnt_device_id) + device = await get_trusted_device(user_id, cookie_value) if not device: raise HTTPException( status_code=HTTPStatus.FORBIDDEN, detail="device-not-trusted: device not in trusted list", ) - # Track last seen (fire-and-forget; don't fail the request if this fails) try: - await touch_trusted_device(key_info.wallet.user, silnt_device_id) + await touch_trusted_device(user_id, cookie_value) except Exception as e: logger.warning(f"touch_trusted_device failed: {e}") @@ -118,21 +137,25 @@ async def require_trusted_device( async def require_trusted_device_admin( request: Request, key_info: WalletTypeInfo = Depends(require_admin_key), - silnt_device_id: Optional[str] = Cookie(default=None), ) -> WalletTypeInfo: - if not silnt_device_id: + if not _is_thrilla_request(request): + return key_info + user_id = key_info.wallet.user + cookie_value = request.cookies.get(cookie_name_for_user(user_id)) + + if not cookie_value: raise HTTPException( status_code=HTTPStatus.FORBIDDEN, detail="device-not-trusted: no device cookie present", ) - device = await get_trusted_device(key_info.wallet.user, silnt_device_id) + device = await get_trusted_device(user_id, cookie_value) if not device: raise HTTPException( status_code=HTTPStatus.FORBIDDEN, detail="device-not-trusted: device not in trusted list", ) try: - await touch_trusted_device(key_info.wallet.user, silnt_device_id) + await touch_trusted_device(user_id, cookie_value) except Exception as e: logger.warning(f"touch_trusted_device failed: {e}") - return key_info + return key_info \ No newline at end of file diff --git a/helpers/dust_check.py b/helpers/dust_check.py index 819c6a5..0e750c7 100644 --- a/helpers/dust_check.py +++ b/helpers/dust_check.py @@ -8,7 +8,9 @@ update_utxo_dust_flag, set_utxo_freeze_auto, clear_utxo_freeze_auto, - get_utxo_freeze_reason + get_utxo_freeze_reason, + get_effective_dust_threshold, + get_silnt_wallet ) @@ -52,8 +54,11 @@ async def evaluate_dust_for_wallet(wallet_id: str) -> int: Returns the number of UTXOs that transitioned from non-dust to dust on this run (useful for the "flagged N new dust UTXO(s)" log line). """ - blindbit = await get_blindbit_config() - threshold = int(blindbit.dust_threshold_sats or 5000) + wallet = await get_silnt_wallet(wallet_id) + if not wallet: + return 0 + threshold = await get_effective_dust_threshold(wallet.user) + blindbit = await get_blindbit_config() mempool = blindbit.mempool_url or "https://mempool.space" utxos = await get_wallet_unspent_utxos_for_dust_check(wallet_id) diff --git a/helpers/transactions.py b/helpers/transactions.py index a6add0a..82cac86 100644 --- a/helpers/transactions.py +++ b/helpers/transactions.py @@ -45,17 +45,14 @@ async def list_wallet_transactions( offset: int = 0, ) -> list[dict]: """ - Build the combined chronological transaction list. No mempool calls here — - everything from local DB. Fast. + Combined chronological transaction list from local DB (no mempool calls). Each row: - { kind: 'receive'|'send'|'self_send', - txid, timestamp, amount_sats, - input_sum, output_sum, # both populated for self_send - output_count, input_count, - labels: [str], - confirmed: bool # heuristic from UTXO state - } + { kind: 'send'|'receive', + txid, timestamp, amount_sats, # negative = net outflow, positive = inflow + input_sum, output_sum, + input_count, output_count, + labels: [str] } """ receives = {r["txid"]: r for r in await get_wallet_receives(wallet_id)} sends = {s["txid"]: s for s in await get_wallet_sends(wallet_id)} @@ -66,35 +63,28 @@ async def list_wallet_transactions( rcv = receives.get(txid) snd = sends.get(txid) - if snd and rcv: - kind = "self_send" - timestamp = snd["spent_at"] or rcv["timestamp"] - # Net amount = what came back minus what went out (negative = net outflow, - # equals fee + any external recipient amount) - amount_sats = rcv["output_sum"] - snd["input_sum"] - labels = rcv["labels"] - input_sum = snd["input_sum"] - output_sum = rcv["output_sum"] - input_count = snd["input_count"] - output_count= rcv["output_count"] - elif snd: - kind = "send" - timestamp = snd["spent_at"] - amount_sats = -snd["input_sum"] # fully outgoing (will refine on detail) - labels = [] - input_sum = snd["input_sum"] - output_sum = 0 - input_count = snd["input_count"] - output_count= 0 + if snd: + # Spent inputs → a send. If the wallet also owns an output (change or + # a consolidation back to self), subtract it so amount = net outflow. + input_sum = snd["input_sum"] + output_sum = rcv["output_sum"] if rcv else 0 + net_out = input_sum - output_sum # sent amount + fee + kind = "send" + timestamp = snd["spent_at"] or (rcv["timestamp"] if rcv else 0) + amount_sats = -net_out # negative = outflow + labels = rcv["labels"] if rcv else [] + input_count = snd["input_count"] + output_count = rcv["output_count"] if rcv else 0 else: - kind = "receive" - timestamp = rcv["timestamp"] - amount_sats = rcv["output_sum"] - labels = rcv["labels"] - input_sum = 0 - output_sum = rcv["output_sum"] - input_count = 0 - output_count= rcv["output_count"] + # No inputs spent → pure receive. + input_sum = 0 + output_sum = rcv["output_sum"] + kind = "receive" + timestamp = rcv["timestamp"] + amount_sats = rcv["output_sum"] # positive = inflow + labels = rcv["labels"] + input_count = 0 + output_count = rcv["output_count"] rows.append({ "kind": kind, @@ -108,7 +98,6 @@ async def list_wallet_transactions( "labels": labels, }) - # Newest first rows.sort(key=lambda r: r["timestamp"], reverse=True) return rows[offset:offset + limit] diff --git a/helpers/user.py b/helpers/user.py new file mode 100644 index 0000000..c3bebf9 --- /dev/null +++ b/helpers/user.py @@ -0,0 +1,30 @@ +from lnbits.settings import settings as lnbits_settings +from lnbits.core.models import WalletTypeInfo +from http import HTTPStatus +from fastapi import HTTPException + +def require_admin(key_info: WalletTypeInfo) -> None: + """Raise 403 if the caller is not an LNbits admin.""" + if not is_lnbits_admin(key_info.wallet.user): + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, + detail="Admin privileges required.", + ) + +def is_lnbits_admin(user_id: str) -> bool: + """ + Check if the user_id has admin rights in LNbits. + Admin users are configured via LNBITS_ADMIN_USERS env var (comma-separated) + plus the LNBITS_SUPER_USER. + """ + # super_user is a single string or None + super_user = getattr(lnbits_settings, "super_user", "") or "" + if user_id and user_id == super_user: + return True + + # admin_users is either a list[str] or a comma-separated string depending + # on LNbits version — handle both + admin_users = getattr(lnbits_settings, "lnbits_admin_users", []) or [] + if isinstance(admin_users, str): + admin_users = [u.strip() for u in admin_users.split(",") if u.strip()] + return user_id in admin_users \ No newline at end of file diff --git a/helpers/wallet.py b/helpers/wallet.py index f7a1e19..f5974dd 100644 --- a/helpers/wallet.py +++ b/helpers/wallet.py @@ -5,6 +5,7 @@ import io import math import struct +from typing import Optional from base64 import b64encode from embit import bip32, bip39, ec, finalizer, script from embit.networks import NETWORKS @@ -38,14 +39,43 @@ p as CURVE_P, ) from embit.ec import SchnorrSig +from mnemonic import Mnemonic +def _validate_or_generate_mnemonic( + plain_mnemonic: Optional[str], +) -> tuple[str, bool]: + """ + Returns (mnemonic_plain, was_generated). + - If plain_mnemonic is provided: validate 12 words + BIP-39 checksum. + - If absent: generate a fresh 12-word seed. + """ + mn = Mnemonic("english") + + if plain_mnemonic: + words = plain_mnemonic.strip().lower().split() + if len(words) != 12: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=f"Mnemonic must be exactly 12 words (got {len(words)}).", + ) + normalized = " ".join(words) + if not mn.check(normalized): + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail="Invalid mnemonic — the checksum (last word) is incorrect. " + "Double-check your recovery phrase.", + ) + return normalized, False + + # Generate a new 12-word mnemonic (128 bits entropy) + return mn.generate(strength=128), True -def get_seed(mnemonic) -> bytes: +def get_seed(mnemonic, passphrase: str = "") -> bytes: """ Re‑creates the BIP‑39 seed from the hard‑coded mnemonic. Returns the 64‑byte seed (as `bytes`). """ - seed = bip39.mnemonic_to_seed(mnemonic) + seed = bip39.mnemonic_to_seed(mnemonic, password=passphrase) return seed @@ -87,8 +117,8 @@ def encode_silent_payment_address( return ret -async def generate_silent_wallet_address(mnemonic, network: str = "mainnet") -> tuple: - seed = get_seed(mnemonic) +async def generate_silent_wallet_address(mnemonic, passphrase="", network: str = "mainnet") -> tuple: + seed = get_seed(mnemonic, passphrase=passphrase) key_material = generate_hardened_keys(seed, network) B_scan = pubkey_point_gen_from_int(int_from_bytes(key_material["scan_priv_key"])) diff --git a/migrations.py b/migrations.py index 1e28b8d..a3801a7 100644 --- a/migrations.py +++ b/migrations.py @@ -50,7 +50,7 @@ async def m001_initial(db): ) await db.execute( """ - CREATE UNIQUE INDEX IF NOT EXISTS idx_silnt_utxos_vout ON silnt.utxos (txid, vout); + CREATE UNIQUE INDEX IF NOT EXISTS idx_silnt_utxos_vout_wallet_id ON silnt.utxos (txid, vout, wallet_id); """ ) @@ -102,4 +102,41 @@ async def m005_trusted_devices(db): ) await db.execute( "CREATE INDEX IF NOT EXISTS trusted_devices_user ON silnt.trusted_devices(user_id)" + ) + +async def m006_user_prefs(db): + await db.execute( + """ + CREATE TABLE IF NOT EXISTS silnt.user_prefs ( + user_id TEXT PRIMARY KEY, + dust_threshold_sats INTEGER DEFAULT NULL, + updated_at INTEGER NOT NULL + ) + """ + ) + +async def m007_bip353_requests(db): + await db.execute( + """ + CREATE TABLE IF NOT EXISTS silnt.bip353_requests ( + id TEXT PRIMARY KEY, + user_id TEXT NOT NULL, + wallet_id TEXT NOT NULL, + sp_address TEXT NOT NULL, + requested_username TEXT NOT NULL, + final_username TEXT, + message TEXT, + status TEXT NOT NULL DEFAULT 'pending', + reject_reason TEXT, + created_at INTEGER NOT NULL, + processed_at INTEGER, + processed_by TEXT + ) + """ + ) + await db.execute( + "CREATE INDEX IF NOT EXISTS bip353_requests_user ON silnt.bip353_requests(user_id, status)" + ) + await db.execute( + "CREATE INDEX IF NOT EXISTS bip353_requests_status ON silnt.bip353_requests(status, created_at)" ) \ No newline at end of file diff --git a/models.py b/models.py index 8b34683..feabe89 100644 --- a/models.py +++ b/models.py @@ -1,20 +1,38 @@ from typing import Optional, List from fastapi import Query -from pydantic import BaseModel +from pydantic import BaseModel, Field +import re + +USERNAME_PATTERN = re.compile(r"^[a-z0-9_\-]{3,20}$") +RESERVED_USERNAMES = { + "admin", "administrator", "root", "support", "help", "info", "abuse", + "postmaster", "webmaster", "system", "anthropic", "claude", "bot", + "moderator", "mod", "service", "noreply", "no-reply", "test", "demo", +} +REQUEST_COOLDOWN_SECONDS = 24 * 3600 +RECENT_REJECT_COOLDOWN = 24 * 3600 +class CreateWallet(BaseModel): + title: str + network: str = "mainnet" + hr_address: Optional[str] = None + mnemonic: Optional[str] = None + passphrase: Optional[str] = None + last_height: Optional[int] = None class BlindbitConfig(BaseModel): blindbit_url: str = "" mempool_url: str = "https://mempool.space" min_scan_height: int = 0 # 0 = no minimum; e.g. 840000 = no scans before block 840000 - max_wallets_per_user: int = 0 # 0 = unlimited + max_wallets_per_user: int = 1 # 0 = unlimited dust_threshold_sats: int = 5000 class CreateWallet(BaseModel): mnemonic: str = None title: str = None network: str = "mainnet" - hr_address: str = None + passphrase: Optional[str] = "" + hr_address: Optional[str] = None last_height: str = None balance: Optional[int] = None @@ -73,16 +91,10 @@ class BuildTxRequest(BaseModel): scan_secret: str -class BroadcastTxRequest(BaseModel): - tx_hex: str - wallet_id: Optional[str] = None - spent_txids: list[str] = [] - spent_outpoints: list[tuple[str, int]] = [] # list of [txid, vout] - - class RecoverKeysRequest(BaseModel): mnemonic: str # encrypted (AES-encrypted with last_height as key) last_height: int # encryption key + birth height + passphrase: Optional[str] = None # NEW: BIP-39 passphrase (plaintext) class Config(BaseModel): sats_denominated: bool = True @@ -124,6 +136,8 @@ class ForgotPasswordRequest(BaseModel): class UpdateUtxoLabel(BaseModel): label: str = '' + wallet_id: str + vout: Optional[int] = None class UpdateUtxoFrozenRequest(BaseModel): frozen: bool @@ -156,4 +170,61 @@ class DeviceConfirmResponse(BaseModel): class DeviceListResponse(BaseModel): devices: List[TrustedDevice] current_device: Optional[str] = None - cap: int \ No newline at end of file + cap: int + +class WhoamiResponse(BaseModel): + user_id: str + username: Optional[str] = None + email: Optional[str] = None + is_admin: bool + +class UserPrefs(BaseModel): + user_id: str + dust_threshold_sats: Optional[int] = None + updated_at: int + +class UpdateUserPrefsRequest(BaseModel): + dust_threshold_sats: Optional[int] = None # None = revert to admin default + +class Bip353Request(BaseModel): + id: str + user_id: str + wallet_id: str + sp_address: str + requested_username: str + final_username: Optional[str] = None + message: Optional[str] = None + status: str # 'pending' | 'approved' | 'rejected' | 'cancelled' + reject_reason: Optional[str] = None + created_at: int + processed_at: Optional[int] = None + processed_by: Optional[str] = None + + +class CreateBip353Request(BaseModel): + wallet_id: str + requested_username: str + message: Optional[str] = Field(default=None, max_length=500) + +class ApproveBip353Request(BaseModel): + final_username: Optional[str] = None # admin may tweak the requested name + +class RejectBip353Request(BaseModel): + reason: str = Field(..., max_length=500) + +class BroadcastOutpoint(BaseModel): + txid: str + vout: int + +class BroadcastTxRequest(BaseModel): + tx_hex: str + wallet_id: str + # full outpoints of the inputs this tx spends + spent_outpoints: List[BroadcastOutpoint] = [] + # optional metadata for richer Activity display before rescan + recipient: Optional[str] = None + amount: Optional[int] = None + fee: Optional[int] = None + # backward-compat: older clients may still send spent_txids + spent_txids: Optional[List[str]] = None + \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 3e440c5..b7099d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ dependencies = [ "embit>=0.8.0", "fastapi>=0.115.13", "httpx>=0.27.0", + "mnemonic>=0.21", "pydantic>=1.10.22", ] diff --git a/templates/silnt/_api_docs.html b/templates/silnt/_api_docs.html index 260c816..dd5cc38 100644 --- a/templates/silnt/_api_docs.html +++ b/templates/silnt/_api_docs.html @@ -1,4 +1,4 @@ -

-
+ --> - Wallet operations (scan, send, generate labeled addresses) are available + Wallet operations (scan, send, generate labeled addresses) as well as Admin configurations are available in the Thrilla mobile/web app, where keys are stored securely on your device. -
+ + +
- + --> - + \ No newline at end of file diff --git a/templates/silnt/index.html b/templates/silnt/index.html index e3d4448..5350699 100644 --- a/templates/silnt/index.html +++ b/templates/silnt/index.html @@ -65,7 +65,7 @@
- +
- Silent Payments Wallet Extension + Thrilla - Silent Payments Wallet
@@ -461,7 +461,7 @@
Confirm Broadcast
{% endblock %} {% block vue_templates %} -

6N2$P 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 HXD|OdP1NCc diff --git a/static/3.png b/static/3.png deleted file mode 100644 index 343f926af8261b643a063f637e7ae71b33b347c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182701 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�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%0DS@+di`ncJ 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 M89l(?cX&hyVZp diff --git a/static/bitcoin-extension.png b/static/bitcoin-extension.png deleted file mode 100644 index 8366c0c2e6b5f71bee59108c6eac86743441576e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5343 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 diff --git a/static/bitcoin-wallet.png b/static/bitcoin-wallet.png new file mode 100644 index 0000000000000000000000000000000000000000..3cd5ac0f074ba29595f531bfed0eac826cc8a17b GIT binary patch literal 12988 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