Nostr bech32 dm (#109)

* nostr: bech32 keys and remember last DM check

* cump to 0.9.2

* make format
This commit is contained in:
calle
2023-02-13 23:19:19 +01:00
committed by GitHub
parent 53aa73b7c7
commit 5ec2c3604e
10 changed files with 84 additions and 19 deletions

View File

@@ -33,6 +33,6 @@ LNBITS_KEY=yourkeyasdasdasd
# NOSTR
# nostr private key to which to receive tokens to
NOSTR_PRIVATE_KEY=hex_nostrprivatekey_here
NOSTR_PRIVATE_KEY=nostr_privatekey_here_hex_or_bech32
# nostr relays (comma separated list)
NOSTR_RELAYS="wss://nostr-pub.wellorder.net"

View File

@@ -115,7 +115,7 @@ cashu info
Returns:
```bash
Version: 0.9.1
Version: 0.9.2
Debug: False
Cashu dir: /home/user/.cashu
Wallet: wallet

View File

@@ -66,4 +66,4 @@ NOSTR_RELAYS = env.list(
)
MAX_ORDER = 64
VERSION = "0.9.1"
VERSION = "0.9.2"

View File

@@ -41,8 +41,10 @@ from cashu.wallet import migrations
from cashu.wallet.crud import (
get_keyset,
get_lightning_invoices,
get_nostr_last_check_timestamp,
get_reserved_proofs,
get_unused_locks,
set_nostr_last_check_timestamp,
)
from cashu.wallet.wallet import Wallet as Wallet
@@ -609,8 +611,8 @@ async def info(ctx: Context):
if TOR:
print(f"Tor enabled: {TOR}")
if NOSTR_PRIVATE_KEY:
client = NostrClient(privatekey_hex=NOSTR_PRIVATE_KEY, connect=False)
print(f"Nostr public key: {client.public_key.hex()}")
client = NostrClient(private_key=NOSTR_PRIVATE_KEY, connect=False)
print(f"Nostr public key: {client.public_key.bech32()}")
print(f"Nostr relays: {NOSTR_RELAYS}")
if SOCKS_HOST:
print(f"Socks proxy: {SOCKS_HOST}:{SOCKS_PORT}")

View File

@@ -1,6 +1,7 @@
import asyncio
import os
import threading
import time
import urllib.parse
from typing import List
@@ -14,7 +15,11 @@ from cashu.core.settings import CASHU_DIR, MINT_URL, NOSTR_PRIVATE_KEY, NOSTR_RE
from cashu.nostr.nostr.client.client import NostrClient
from cashu.nostr.nostr.event import Event
from cashu.nostr.nostr.key import PublicKey
from cashu.wallet.crud import get_keyset
from cashu.wallet.crud import (
get_keyset,
get_nostr_last_check_timestamp,
set_nostr_last_check_timestamp,
)
from cashu.wallet.wallet import Wallet as Wallet
@@ -235,9 +240,14 @@ async def send_nostr(ctx: Context, amount: int, pubkey: str, verbose: bool, yes:
# we only use ephemeral private keys for sending
client = NostrClient(relays=NOSTR_RELAYS)
if verbose:
print(f"Your ephemeral nostr private key: {client.private_key.hex()}")
await asyncio.sleep(1)
client.dm(token, PublicKey(bytes.fromhex(pubkey)))
print(f"Your ephemeral nostr private key: {client.private_key.bech32()}")
if pubkey.startswith("npub"):
pubkey_to = PublicKey().from_npub(pubkey)
else:
pubkey_to = PublicKey(bytes.fromhex(pubkey))
client.dm(token, pubkey_to)
print(f"Token sent to {pubkey}")
client.close()
@@ -248,10 +258,10 @@ async def receive_nostr(ctx: Context, verbose: bool):
"Warning: No nostr private key set! You don't have NOSTR_PRIVATE_KEY set in your .env file. I will create a random private key for this session but I will not remember it."
)
print("")
client = NostrClient(privatekey_hex=NOSTR_PRIVATE_KEY, relays=NOSTR_RELAYS)
print(f"Your nostr public key: {client.public_key.hex()}")
client = NostrClient(private_key=NOSTR_PRIVATE_KEY, relays=NOSTR_RELAYS)
print(f"Your nostr public key: {client.public_key.bech32()}")
if verbose:
print(f"Your nostr private key (do not share!): {client.private_key.hex()}")
print(f"Your nostr private key (do not share!): {client.private_key.bech32()}")
await asyncio.sleep(2)
def get_token_callback(event: Event, decrypted_content):
@@ -267,12 +277,16 @@ async def receive_nostr(ctx: Context, verbose: bool):
except Exception as e:
pass
# determine timestamp of last check so we don't scan all historical DMs
wallet: Wallet = ctx.obj["WALLET"]
last_check = await get_nostr_last_check_timestamp(db=wallet.db)
if last_check:
last_check -= 60 * 60 # 1 hour tolerance
await set_nostr_last_check_timestamp(timestamp=int(time.time()), db=wallet.db)
t = threading.Thread(
target=client.get_dm,
args=(
client.public_key,
get_token_callback,
),
args=(client.public_key, get_token_callback, {"since": last_check}),
name="Nostr DM",
)
t.start()

View File

@@ -334,3 +334,27 @@ async def update_lightning_invoice(
hash,
),
)
async def set_nostr_last_check_timestamp(
db: Database,
timestamp: int,
conn: Optional[Connection] = None,
):
await (conn or db).execute(
f"UPDATE nostr SET last = ? WHERE type = ?",
(timestamp, "dm"),
)
async def get_nostr_last_check_timestamp(
db: Database,
conn: Optional[Connection] = None,
):
row = await (conn or db).fetchone(
f"""
SELECT last from nostr WHERE type = ?
""",
("dm",),
)
return row[0] if row else None

View File

@@ -144,3 +144,28 @@ async def m006_invoices(db: Database):
);
"""
)
async def m007_nostr(db: Database):
"""
Stores timestamps of nostr operations.
"""
await db.execute(
f"""
CREATE TABLE IF NOT EXISTS nostr (
type TEXT NOT NULL,
last TIMESTAMP DEFAULT NULL
)
"""
)
await db.execute(
f"""
INSERT INTO nostr
(type, last)
VALUES (?, ?)
""",
(
"dm",
None,
),
)

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "cashu"
version = "0.9.1"
version = "0.9.2"
description = "Ecash wallet and mint."
authors = ["calle <callebtc@protonmail.com>"]
license = "MIT"

View File

@@ -13,7 +13,7 @@ entry_points = {"console_scripts": ["cashu = cashu.wallet.cli:cli"]}
setuptools.setup(
name="cashu",
version="0.9.1",
version="0.9.2",
description="Ecash wallet and mint for Bitcoin Lightning",
long_description=long_description,
long_description_content_type="text/markdown",