Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: code quality #14

Merged
merged 2 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: lint
on:
push:
branches:
- main
pull_request:

jobs:
lint:
uses: lnbits/lnbits/.github/workflows/lint.yml@dev
15 changes: 7 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
- 'v[0-9]+.[0-9]+.[0-9]+'

jobs:

release:
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -34,12 +33,12 @@ jobs:
- name: Create pull request in extensions repo
env:
GH_TOKEN: ${{ secrets.EXT_GITHUB }}
repo_name: "${{ github.event.repository.name }}"
tag: "${{ github.ref_name }}"
branch: "update-${{ github.event.repository.name }}-${{ github.ref_name }}"
title: "[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}"
body: "https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}"
archive: "https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip"
repo_name: '${{ github.event.repository.name }}'
tag: '${{ github.ref_name }}'
branch: 'update-${{ github.event.repository.name }}-${{ github.ref_name }}'
title: '[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}'
body: 'https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}'
archive: 'https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip'
run: |
cd lnbits-extensions
git checkout -b $branch
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
__pycache__
node_modules
.mypy_cache
.venv
12 changes: 12 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"semi": false,
"arrowParens": "avoid",
"insertPragma": false,
"printWidth": 80,
"proseWrap": "preserve",
"singleQuote": true,
"trailingComma": "none",
"useTabs": false,
"bracketSameLine": false,
"bracketSpacing": false
}
47 changes: 47 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
all: format check

format: prettier black ruff

check: mypy pyright checkblack checkruff checkprettier

prettier:
poetry run ./node_modules/.bin/prettier --write .
pyright:
poetry run ./node_modules/.bin/pyright

mypy:
poetry run mypy .

black:
poetry run black .

ruff:
poetry run ruff check . --fix

checkruff:
poetry run ruff check .

checkprettier:
poetry run ./node_modules/.bin/prettier --check .

checkblack:
poetry run black --check .

checkeditorconfig:
editorconfig-checker

test:
PYTHONUNBUFFERED=1 \
DEBUG=true \
poetry run pytest
install-pre-commit-hook:
@echo "Installing pre-commit hook to git"
@echo "Uninstall the hook with poetry run pre-commit uninstall"
poetry run pre-commit install

pre-commit:
poetry run pre-commit run --all-files


checkbundle:
@echo "skipping checkbundle"
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Onchain Wallet (watch-only) - <small>[LNbits](https://github.com/lnbits/lnbits) extension</small>

<small>For more about LNBits extension check [this tutorial](https://github.com/lnbits/lnbits/wiki/LNbits-Extensions)</small>

## Monitor an onchain wallet and generate addresses for onchain payments
Expand Down
17 changes: 6 additions & 11 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from fastapi import APIRouter

from lnbits.db import Database
from lnbits.helpers import template_renderer

db = Database("ext_watchonly")
from .crud import db
from .views import watchonly_generic_router
from .views_api import watchonly_api_router

watchonly_static_files = [
{
Expand All @@ -13,11 +12,7 @@
]

watchonly_ext: APIRouter = APIRouter(prefix="/watchonly", tags=["watchonly"])
watchonly_ext.include_router(watchonly_generic_router)
watchonly_ext.include_router(watchonly_api_router)


def watchonly_renderer():
return template_renderer(["watchonly/templates"])


from .views import * # noqa: F401,F403
from .views_api import * # noqa: F401,F403
__all__ = ["watchonly_ext", "watchonly_static_files", "db"]
27 changes: 15 additions & 12 deletions crud.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import json
from typing import List, Optional
from typing import Optional

from lnbits.db import Database
from lnbits.helpers import urlsafe_short_hash

from . import db
from .helpers import derive_address
from .models import Address, Config, WalletAccount

##########################WALLETS####################
db = Database("ext_watchonly")


async def create_watch_wallet(user: str, w: WalletAccount) -> WalletAccount:
Expand Down Expand Up @@ -53,7 +53,7 @@ async def get_watch_wallet(wallet_id: str) -> Optional[WalletAccount]:
return WalletAccount.from_row(row) if row else None


async def get_watch_wallets(user: str, network: str) -> List[WalletAccount]:
async def get_watch_wallets(user: str, network: str) -> list[WalletAccount]:
rows = await db.fetchall(
"""SELECT * FROM watchonly.wallets WHERE "user" = ? AND network = ?""",
(user, network),
Expand Down Expand Up @@ -120,7 +120,7 @@ async def create_fresh_addresses(
start_address_index: int,
end_address_index: int,
change_address=False,
) -> List[Address]:
) -> list[Address]:
if start_address_index > end_address_index:
return []

Expand Down Expand Up @@ -152,7 +152,8 @@ async def create_fresh_addresses(
rows = await db.fetchall(
"""
SELECT * FROM watchonly.addresses
WHERE wallet = ? AND branch_index = ? AND address_index >= ? AND address_index < ?
WHERE wallet = ? AND branch_index = ?
AND address_index >= ? AND address_index < ?
ORDER BY branch_index, address_index
""",
(wallet_id, branch_index, start_address_index, end_address_index),
Expand Down Expand Up @@ -185,7 +186,7 @@ async def get_address_at_index(
return Address.from_row(row) if row else None


async def get_addresses(wallet_id: str) -> List[Address]:
async def get_addresses(wallet_id: str) -> list[Address]:
rows = await db.fetchall(
"""
SELECT * FROM watchonly.addresses WHERE wallet = ?
Expand All @@ -197,22 +198,24 @@ async def get_addresses(wallet_id: str) -> List[Address]:
return [Address(**row) for row in rows]


async def update_address(id: str, **kwargs) -> Optional[Address]:
async def update_address(address_id: str, **kwargs) -> Address:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])

await db.execute(
f"""UPDATE watchonly.addresses SET {q} WHERE id = ? """,
(*kwargs.values(), id),
(*kwargs.values(), address_id),
)
row = await db.fetchone("SELECT * FROM watchonly.addresses WHERE id = ?", (id,))
return Address.from_row(row) if row else None
row = await db.fetchone(
"SELECT * FROM watchonly.addresses WHERE id = ?", (address_id,)
)
assert row, "updated address not found"
return Address.from_row(row)


async def delete_addresses_for_wallet(wallet_id: str) -> None:
await db.execute("DELETE FROM watchonly.addresses WHERE wallet = ?", (wallet_id,))


######################CONFIG#######################
async def create_config(user: str) -> Config:
config = Config()
await db.execute(
Expand Down
2 changes: 1 addition & 1 deletion description.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ Can be used directly with LNbits $10 hardware wallet/

Monitor an extended public key and generate deterministic fresh public keys with this simple watch only wallet. Invoice payments can also be generated, both through a publically shareable page and API.

Other extensions can make use of this extension to add onchain functionality.
Other extensions can make use of this extension to add onchain functionality.
9 changes: 5 additions & 4 deletions helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ def parse_key(masterpub: str) -> Tuple[Descriptor, Optional[dict]]:
# check depth
if k.key.depth != 3:
raise ValueError(
"Non-standard depth. Only bip44, bip49 and bip84 are supported with bare xpubs. For custom derivation paths use descriptors."
"Non-standard depth. Only bip44, bip49 and bip84 are supported "
"with bare xpubs. For custom derivation paths use descriptors."
)
# if allowed derivation is not provided use default /{0,1}/*
if k.allowed_derivation is None:
Expand All @@ -43,11 +44,11 @@ def parse_key(masterpub: str) -> Tuple[Descriptor, Optional[dict]]:
if version in [net["xpub"], net["ypub"], net["zpub"]]:
network = net
if version == net["xpub"]:
desc = Descriptor.from_string("pkh(%s)" % str(k))
desc = Descriptor.from_string(f"pkh({k!s})")
elif version == net["ypub"]:
desc = Descriptor.from_string("sh(wpkh(%s))" % str(k))
desc = Descriptor.from_string(f"sh(wpkh({k!s}))")
elif version == net["zpub"]:
desc = Descriptor.from_string("wpkh(%s)" % str(k))
desc = Descriptor.from_string(f"wpkh({k!s}")
break
# we didn't find correct version
if not network:
Expand Down
21 changes: 14 additions & 7 deletions migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,36 @@ async def m001_initial(db):

async def m002_add_columns_to_adresses(db):
"""
Add 'branch_index', 'address_index', 'has_activity' and 'note' columns to the 'addresses' table
Add 'branch_index', 'address_index', 'has_activity' and
'note' columns to the 'addresses' table
"""

await db.execute(
"ALTER TABLE watchonly.addresses ADD COLUMN branch_index INTEGER NOT NULL DEFAULT 0;"
"""
ALTER TABLE watchonly.addresses
ADD COLUMN branch_index INTEGER NOT NULL DEFAULT 0
"""
)
await db.execute(
"ALTER TABLE watchonly.addresses ADD COLUMN address_index INTEGER NOT NULL DEFAULT 0;"
"""
ALTER TABLE watchonly.addresses
ADD COLUMN address_index INTEGER NOT NULL DEFAULT 0
"""
)
await db.execute(
"ALTER TABLE watchonly.addresses ADD COLUMN has_activity BOOLEAN DEFAULT false;"
"ALTER TABLE watchonly.addresses ADD COLUMN has_activity BOOLEAN DEFAULT false"
)
await db.execute("ALTER TABLE watchonly.addresses ADD COLUMN note TEXT;")
await db.execute("ALTER TABLE watchonly.addresses ADD COLUMN note TEXT")


async def m003_add_columns_to_wallets(db):
"""
Add 'type' and 'fingerprint' columns to the 'wallets' table
"""

await db.execute("ALTER TABLE watchonly.wallets ADD COLUMN type TEXT;")
await db.execute("ALTER TABLE watchonly.wallets ADD COLUMN type TEXT")
await db.execute(
"ALTER TABLE watchonly.wallets ADD COLUMN fingerprint TEXT NOT NULL DEFAULT '';"
"ALTER TABLE watchonly.wallets ADD COLUMN fingerprint TEXT NOT NULL DEFAULT ''"
)


Expand Down
12 changes: 6 additions & 6 deletions models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from sqlite3 import Row
from typing import List, Optional
from typing import Optional

from fastapi import Query
from pydantic import BaseModel
Expand Down Expand Up @@ -69,9 +69,9 @@ class MasterPublicKey(BaseModel):


class CreatePsbt(BaseModel):
masterpubs: List[MasterPublicKey]
inputs: List[TransactionInput]
outputs: List[TransactionOutput]
masterpubs: list[MasterPublicKey]
inputs: list[TransactionInput]
outputs: list[TransactionOutput]
fee_rate: int
tx_size: int

Expand All @@ -81,8 +81,8 @@ class SerializedTransaction(BaseModel):


class ExtractPsbt(BaseModel):
psbtBase64 = "" # // todo snake case
inputs: List[SerializedTransaction]
psbt_base64 = ""
inputs: list[SerializedTransaction]
network = "Mainnet"


Expand Down
59 changes: 59 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading