diff --git a/Makefile b/Makefile
index 4f99f1da..ebf2a872 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ format: prettier isort black
check: mypy checkprettier checkisort checkblack
-prettier: $(shell find lnbits -name "*.js" -name ".html")
+prettier: $(shell find lnbits -name "*.js" -o -name ".html")
./node_modules/.bin/prettier --write lnbits/static/js/*.js lnbits/core/static/js/*.js lnbits/extensions/*/templates/*/*.html ./lnbits/core/templates/core/*.html lnbits/templates/*.html lnbits/extensions/*/static/js/*.js lnbits/extensions/*/static/components/*/*.js lnbits/extensions/*/static/components/*/*.html
black:
@@ -18,7 +18,7 @@ mypy:
isort:
poetry run isort .
-checkprettier: $(shell find lnbits -name "*.js" -name ".html")
+checkprettier: $(shell find lnbits -name "*.js" -o -name ".html")
./node_modules/.bin/prettier --check lnbits/static/js/*.js lnbits/core/static/js/*.js lnbits/extensions/*/templates/*/*.html ./lnbits/core/templates/core/*.html lnbits/templates/*.html lnbits/extensions/*/static/js/*.js lnbits/extensions/*/static/components/*/*.js lnbits/extensions/*/static/components/*/*.html
checkblack:
diff --git a/flake.nix b/flake.nix
index af25ba5c..d9f0f1f0 100644
--- a/flake.nix
+++ b/flake.nix
@@ -5,7 +5,7 @@
};
outputs = { self, nixpkgs, poetry2nix }@inputs:
let
- supportedSystems = [ "x86_64-linux" "aarch64-linux" ];
+ supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forSystems = systems: f:
nixpkgs.lib.genAttrs systems
(system: f system (import nixpkgs { inherit system; overlays = [ poetry2nix.overlay self.overlays.default ]; }));
diff --git a/lnbits/bolt11.py b/lnbits/bolt11.py
index 32b43feb..41b73b7d 100644
--- a/lnbits/bolt11.py
+++ b/lnbits/bolt11.py
@@ -1,7 +1,6 @@
import hashlib
import re
import time
-from binascii import unhexlify
from decimal import Decimal
from typing import List, NamedTuple, Optional
@@ -108,7 +107,7 @@ def decode(pr: str) -> Invoice:
message = bytearray([ord(c) for c in hrp]) + data.tobytes()
sig = signature[0:64]
if invoice.payee:
- key = VerifyingKey.from_string(unhexlify(invoice.payee), curve=SECP256k1)
+ key = VerifyingKey.from_string(bytes.fromhex(invoice.payee), curve=SECP256k1)
key.verify(sig, message, hashlib.sha256, sigdecode=sigdecode_string)
else:
keys = VerifyingKey.from_public_key_recovery(
@@ -131,7 +130,7 @@ def encode(options):
if options["timestamp"]:
addr.date = int(options["timestamp"])
- addr.paymenthash = unhexlify(options["paymenthash"])
+ addr.paymenthash = bytes.fromhex(options["paymenthash"])
if options["description"]:
addr.tags.append(("d", options["description"]))
@@ -149,8 +148,8 @@ def encode(options):
while len(splits) >= 5:
route.append(
(
- unhexlify(splits[0]),
- unhexlify(splits[1]),
+ bytes.fromhex(splits[0]),
+ bytes.fromhex(splits[1]),
int(splits[2]),
int(splits[3]),
int(splits[4]),
@@ -235,7 +234,7 @@ def lnencode(addr, privkey):
raise ValueError("Must include either 'd' or 'h'")
# We actually sign the hrp, then data (padded to 8 bits with zeroes).
- privkey = secp256k1.PrivateKey(bytes(unhexlify(privkey)))
+ privkey = secp256k1.PrivateKey(bytes.fromhex(privkey))
sig = privkey.ecdsa_sign_recoverable(
bytearray([ord(c) for c in hrp]) + data.tobytes()
)
@@ -261,7 +260,7 @@ class LnAddr(object):
def __str__(self):
return "LnAddr[{}, amount={}{} tags=[{}]]".format(
- hexlify(self.pubkey.serialize()).decode("utf-8"),
+ bytes.hex(self.pubkey.serialize()).decode("utf-8"),
self.amount,
self.currency,
", ".join([k + "=" + str(v) for k, v in self.tags]),
diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py
index 7d9f2a5b..a80fadf2 100644
--- a/lnbits/core/crud.py
+++ b/lnbits/core/crud.py
@@ -454,6 +454,7 @@ async def update_payment_details(
async def update_payment_extra(
payment_hash: str,
extra: dict,
+ outgoing: bool = False,
conn: Optional[Connection] = None,
) -> None:
"""
@@ -461,8 +462,10 @@ async def update_payment_extra(
Old values in the `extra` JSON object will be kept unless the new `extra` overwrites them.
"""
+ amount_clause = "AND amount < 0" if outgoing else "AND amount > 0"
+
row = await (conn or db).fetchone(
- "SELECT hash, extra from apipayments WHERE hash = ?",
+ f"SELECT hash, extra from apipayments WHERE hash = ? {amount_clause}",
(payment_hash,),
)
if not row:
@@ -471,10 +474,7 @@ async def update_payment_extra(
db_extra.update(extra)
await (conn or db).execute(
- """
- UPDATE apipayments SET extra = ?
- WHERE hash = ?
- """,
+ f"UPDATE apipayments SET extra = ? WHERE hash = ? {amount_clause} ",
(json.dumps(db_extra), payment_hash),
)
diff --git a/lnbits/core/migrations.py b/lnbits/core/migrations.py
index 81413246..41ba5644 100644
--- a/lnbits/core/migrations.py
+++ b/lnbits/core/migrations.py
@@ -224,7 +224,7 @@ async def m007_set_invoice_expiries(db):
)
).fetchall()
if len(rows):
- logger.info(f"Mirgraion: Checking expiry of {len(rows)} invoices")
+ logger.info(f"Migration: Checking expiry of {len(rows)} invoices")
for i, (
payment_request,
checking_id,
@@ -238,7 +238,7 @@ async def m007_set_invoice_expiries(db):
invoice.date + invoice.expiry
)
logger.info(
- f"Mirgraion: {i+1}/{len(rows)} setting expiry of invoice {invoice.payment_hash} to {expiration_date}"
+ f"Migration: {i+1}/{len(rows)} setting expiry of invoice {invoice.payment_hash} to {expiration_date}"
)
await db.execute(
"""
diff --git a/lnbits/core/models.py b/lnbits/core/models.py
index 65c72b41..138a39f7 100644
--- a/lnbits/core/models.py
+++ b/lnbits/core/models.py
@@ -4,13 +4,13 @@ import hmac
import json
import time
from sqlite3 import Row
-from typing import Dict, List, NamedTuple, Optional
+from typing import Dict, List, Optional
from ecdsa import SECP256k1, SigningKey # type: ignore
from fastapi import Query
from lnurl import encode as lnurl_encode # type: ignore
from loguru import logger
-from pydantic import BaseModel, Extra, validator
+from pydantic import BaseModel
from lnbits.db import Connection
from lnbits.helpers import url_for
diff --git a/lnbits/core/services.py b/lnbits/core/services.py
index 336d2665..8dc973e7 100644
--- a/lnbits/core/services.py
+++ b/lnbits/core/services.py
@@ -1,6 +1,5 @@
import asyncio
import json
-from binascii import unhexlify
from io import BytesIO
from typing import Dict, List, Optional, Tuple
from urllib.parse import parse_qs, urlparse
@@ -13,12 +12,7 @@ from loguru import logger
from lnbits import bolt11
from lnbits.db import Connection
-from lnbits.decorators import (
- WalletTypeInfo,
- get_key_type,
- require_admin_key,
- require_invoice_key,
-)
+from lnbits.decorators import WalletTypeInfo, require_admin_key
from lnbits.helpers import url_for, urlsafe_short_hash
from lnbits.requestvars import g
from lnbits.settings import (
@@ -308,7 +302,7 @@ async def perform_lnurlauth(
) -> Optional[LnurlErrorResponse]:
cb = urlparse(callback)
- k1 = unhexlify(parse_qs(cb.query)["k1"][0])
+ k1 = bytes.fromhex(parse_qs(cb.query)["k1"][0])
key = wallet.wallet.lnurlauth_key(cb.netloc)
diff --git a/lnbits/core/tasks.py b/lnbits/core/tasks.py
index b57e2625..e11f764b 100644
--- a/lnbits/core/tasks.py
+++ b/lnbits/core/tasks.py
@@ -4,7 +4,6 @@ from typing import Dict
import httpx
from loguru import logger
-from lnbits.helpers import get_current_extension_name
from lnbits.tasks import SseListenersDict, register_invoice_listener
from . import db
diff --git a/lnbits/core/templates/core/wallet.html b/lnbits/core/templates/core/wallet.html
index e2edfdca..9de96956 100644
--- a/lnbits/core/templates/core/wallet.html
+++ b/lnbits/core/templates/core/wallet.html
@@ -231,7 +231,7 @@
This extension allows you to connect a Bleskomat ATM to an lnbits wallet. It will work with both the - open-source DIY Bleskomat ATM project as well as the - commercial Bleskomat ATM. + commercial Bleskomat ATM.
(QR for create the card in (QR for wipe the card in SubmarineSwap: raise refund_privkey = ec.PrivateKey(os.urandom(32), True, net) - refund_pubkey_hex = hexlify(refund_privkey.sec()).decode("UTF-8") + refund_pubkey_hex = bytes.hex(refund_privkey.sec()).decode("UTF-8") res = req_wrap( "post", @@ -121,7 +120,7 @@ async def create_reverse_swap( return False claim_privkey = ec.PrivateKey(os.urandom(32), True, net) - claim_pubkey_hex = hexlify(claim_privkey.sec()).decode("UTF-8") + claim_pubkey_hex = bytes.hex(claim_privkey.sec()).decode("UTF-8") preimage = os.urandom(32) preimage_hash = sha256(preimage).hexdigest() @@ -311,12 +310,12 @@ async def create_onchain_tx( sequence = 0xFFFFFFFE else: privkey = ec.PrivateKey.from_wif(swap.claim_privkey) - preimage = unhexlify(swap.preimage) + preimage = bytes.fromhex(swap.preimage) onchain_address = swap.onchain_address sequence = 0xFFFFFFFF locktime = swap.timeout_block_height - redeem_script = unhexlify(swap.redeem_script) + redeem_script = bytes.fromhex(swap.redeem_script) fees = get_fee_estimation() @@ -324,7 +323,7 @@ async def create_onchain_tx( script_pubkey = script.address_to_scriptpubkey(onchain_address) - vin = [TransactionInput(unhexlify(txid), vout_cnt, sequence=sequence)] + vin = [TransactionInput(bytes.fromhex(txid), vout_cnt, sequence=sequence)] vout = [TransactionOutput(vout_amount - fees, script_pubkey)] tx = Transaction(vin=vin, vout=vout) diff --git a/lnbits/extensions/boltz/mempool.py b/lnbits/extensions/boltz/mempool.py index a64cadad..c7d572a9 100644 --- a/lnbits/extensions/boltz/mempool.py +++ b/lnbits/extensions/boltz/mempool.py @@ -1,6 +1,5 @@ import asyncio import json -from binascii import hexlify import httpx import websockets @@ -84,7 +83,7 @@ def get_mempool_blockheight() -> int: async def send_onchain_tx(tx: Transaction): - raw = hexlify(tx.serialize()) + raw = bytes.hex(tx.serialize()) logger.debug(f"Boltz - mempool sending onchain tx...") req_wrap( "post", diff --git a/lnbits/extensions/boltz/templates/boltz/_api_docs.html b/lnbits/extensions/boltz/templates/boltz/_api_docs.html index eea35ab6..0edc413a 100644 --- a/lnbits/extensions/boltz/templates/boltz/_api_docs.html +++ b/lnbits/extensions/boltz/templates/boltz/_api_docs.html @@ -24,12 +24,13 @@
Link : - https://boltz.exchange
More details Created by, - dnidni
diff --git a/lnbits/extensions/cashu/crud.py b/lnbits/extensions/cashu/crud.py index 773a11fd..23f808c1 100644 --- a/lnbits/extensions/cashu/crud.py +++ b/lnbits/extensions/cashu/crud.py @@ -1,7 +1,6 @@ import os import random import time -from binascii import hexlify, unhexlify from typing import Any, List, Optional, Union from cashu.core.base import MintKeyset diff --git a/lnbits/extensions/cashu/templates/cashu/_cashu.html b/lnbits/extensions/cashu/templates/cashu/_cashu.html index 952fe7e1..370e9eb4 100644 --- a/lnbits/extensions/cashu/templates/cashu/_cashu.html +++ b/lnbits/extensions/cashu/templates/cashu/_cashu.html @@ -4,9 +4,24 @@Create Cashu ecash mints and wallets.
Created by - arcbtc, - vlad, - calle.arcbtc, + vlad, + calle. diff --git a/lnbits/extensions/cashu/templates/cashu/mint.html b/lnbits/extensions/cashu/templates/cashu/mint.html index ee6ab606..bcb919ff 100644 --- a/lnbits/extensions/cashu/templates/cashu/mint.html +++ b/lnbits/extensions/cashu/templates/cashu/mint.html @@ -11,6 +11,7 @@ >This is a - Cashu mint. Cashu is an ecash system for Bitcoin. diff --git a/lnbits/extensions/cashu/templates/cashu/wallet.html b/lnbits/extensions/cashu/templates/cashu/wallet.html index 88dffe7c..d075009e 100644 --- a/lnbits/extensions/cashu/templates/cashu/wallet.html +++ b/lnbits/extensions/cashu/templates/cashu/wallet.html @@ -159,7 +159,7 @@ page_container %} size="lg" color="secondary" class="q-mr-md cursor-pointer" - @click="recheckInvoice(props.row.hash)" + @click="checkInvoice(props.row.hash)" > Check @@ -616,10 +616,10 @@ page_container %} >
Connect your LNbits instance to a
- Discord Bot
leveraging LNbits as a community based lightning node.
Created by,
- Chris LennonChris Lennon
Based on User Manager, by
- Ben ArcBen Arc
+ Gerty (your bitcoin assistant): Use the software Gerty or
+ hardware Gerty
+
+ Created by,
+ Black Coffee,
+ Ben Arc
+
+++"{{fun_satoshi_quotes["quote"]}}"
+ ~ Satoshi {{fun_satoshi_quotes["date"]}} +
+ {{item[0].value}}: {{item[1].value}} +
++ {{item[0].value}}: {{item[1].value}} +
++ {{item[0].value}}: {{item[1].value}} +
+- Hivemind is a Bitcoin sidechain - project for a peer-to-peer oracle protocol that absorbs accurate data into - a blockchain so that Bitcoin users can speculate in prediction markets. + Hivemind + is a Bitcoin sidechain project for a peer-to-peer oracle protocol that + absorbs accurate data into a blockchain so that Bitcoin users can + speculate in prediction markets.
These markets have the potential to revolutionize the emergence of @@ -17,8 +18,8 @@
This extension will become fully operative when the - BIP300 soft-fork gets activated and - Bitcoin Hivemind is launched. + BIP300 + soft-fork gets activated and Bitcoin Hivemind is launched.
diff --git a/lnbits/extensions/invoices/templates/invoices/pay.html b/lnbits/extensions/invoices/templates/invoices/pay.html index 7b6452dc..636dbc90 100644 --- a/lnbits/extensions/invoices/templates/invoices/pay.html +++ b/lnbits/extensions/invoices/templates/invoices/pay.html @@ -251,10 +251,13 @@ block page %} @hide="closeQrCodeDialog" >Add a wallet / Import wallet on BlueWallet or
diff --git a/lnbits/extensions/lndhub/templates/lndhub/_lndhub.html b/lnbits/extensions/lndhub/templates/lndhub/_lndhub.html
index a15cab8f..73097dbf 100644
--- a/lnbits/extensions/lndhub/templates/lndhub/_lndhub.html
+++ b/lnbits/extensions/lndhub/templates/lndhub/_lndhub.html
@@ -3,16 +3,17 @@
LndHub is a protocol invented by - BlueWallet that allows mobile - wallets to query payments and balances, generate invoices and make - payments from accounts that exist on a server. The protocol is a - collection of HTTP endpoints exposed through the internet. + BlueWallet + that allows mobile wallets to query payments and balances, generate + invoices and make payments from accounts that exist on a server. The + protocol is a collection of HTTP endpoints exposed through the internet.
For a wallet that supports it, reading a QR code that contains the URL along with secret access credentials should enable access. Currently it - is supported by Zeus and - BlueWallet. + is supported by + Zeus and + BlueWallet.
+ {{ ngrok }} +
+
+
+ 1. Create a Domain by clicking "NEW DOMAIN"\
+ 2. Fill the options for your DOMAIN
+ - select the wallet
+ - select the fiat currency the invoice will be denominated in
+ - select an amount in fiat to charge users for verification
+ - enter the domain (or subdomain) you want to provide verification
+ for
+ 3. You can then use share your signup link with your users to allow them
+ to sign up *Note, you must own this domain and have access to a web
+ server*
+
+ Installation
+
+ In order for this to work, you need to have ownership of a domain name,
+ and access to a web server that this domain is pointed to. Then, you'll
+ need to set up a proxy that points
+ `https://{your_domain}/.well-known/nostr.json` to
+ `https://{your_lnbits}/nostrnip5/api/v1/domain/{domain_id}/nostr.json`
+
+ Example nginx configuration
+
+
+
+
+ location /.well-known/nostr.json {
+ proxy_pass
+ https://{your_lnbits}/nostrnip5/api/v1/domain/{domain_id}/nostr.json;
+ proxy_set_header Host {your_lnbits};
+ proxy_ssl_server_name on;
+
+ expires 5m;
+ add_header Cache-Control "public,
+ no-transform";
+
+ proxy_cache nip5_cache;
+ proxy_cache_lock on;
+ proxy_cache_valid 200 300s;
+ proxy_cache_use_stale error timeout
+ invalid_header updating http_500 http_502 http_503 http_504;
+ }
+
+
GET /nostrnip5/api/v1/domains
+ {"X-Api-Key": <invoice_key>}[<domain_object>, ...]
+ curl -X GET {{ request.base_url }}nostrnip5/api/v1/domains -H
+ "X-Api-Key: <invoice_key>"
+
+ GET /nostrnip5/api/v1/addresses
+ {"X-Api-Key": <invoice_key>}[<address_object>, ...]
+ curl -X GET {{ request.base_url }}nostrnip5/api/v1/addresses -H
+ "X-Api-Key: <invoice_key>"
+
+ GET
+ /nostrnip5/api/v1/domain/{domain_id}
+ {"X-Api-Key": <invoice_key>}{domain_object}
+ curl -X GET {{ request.base_url }}nostrnip5/api/v1/domain/{domain_id}
+ -H "X-Api-Key: <invoice_key>"
+
+ POST /nostrnip5/api/v1/domain
+ {"X-Api-Key": <invoice_key>}{domain_object}
+ curl -X POST {{ request.base_url }}nostrnip5/api/v1/domain -H
+ "X-Api-Key: <invoice_key>"
+
+ POST
+ /nostrnip5/api/v1/domain/{domain_id}/address
+ {"X-Api-Key": <invoice_key>}{address_object}
+ curl -X POST {{ request.base_url
+ }}nostrnip5/api/v1/domain/{domain_id}/address -H "X-Api-Key:
+ <invoice_key>"
+
+ POST
+ /invoices/api/v1/invoice/{invoice_id}/payments
+ {payment_object}
+ curl -X POST {{ request.base_url
+ }}invoices/api/v1/invoice/{invoice_id}/payments -H "X-Api-Key:
+ <invoice_key>"
+
+ GET
+ /nostrnip5/api/v1/domain/{domain_id}/payments/{payment_hash}
+ curl -X GET {{ request.base_url
+ }}nostrnip5/api/v1/domain/{domain_id}/payments/{payment_hash} -H
+ "X-Api-Key: <invoice_key>"
+
+ + Allow users to NIP-05 verify themselves at a domain you + control +
++ You can use this page to change the public key associated with your + NIP-5 identity. +
++ Your current NIP-5 identity is {{ address.local_part }}@{{ domain.domain + }} with nostr public key {{ address.pubkey }}. +
+ +Input your new pubkey below to update it.
+ ++ Success! Your username is now active at {{ successData.local_part }}@{{ + domain }}. Please add this to your nostr profile accordingly. If you ever + need to rotate your keys, you can still keep your identity! +
+ ++ Bookmark this link: + {{ base_url }}nostrnip5/rotate/{{ domain_id }}/{{ + successData.address_id }} +
++ In case you ever need to change your pubkey, you can still keep this NIP-5 + identity. Just come back to the above linked page to change the pubkey + associated to your identity. +
+ {% endraw %} ++ You can use this page to get NIP-5 verified on the nostr protocol under + the {{ domain.domain }} domain. +
++ The current price is + {{ "{:0,.2f}".format(domain.amount / 100) }} {{ domain.currency }} + for an account (if you do not own the domain, the service provider can + disable at any time). +
+ +After submitting payment, your address will be
+ +and will be tied to this nostr pubkey
+ +