Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
5baee14
init: first integration pass
talvasconcelos Apr 15, 2026
35fceeb
hardening and securing tab handling
talvasconcelos Apr 16, 2026
a988871
chore: clean up
talvasconcelos Apr 20, 2026
fd123c2
chore: clean test file
talvasconcelos Apr 20, 2026
3cbc2d6
fix: tab button standard
talvasconcelos Apr 20, 2026
d6c1e6d
standard button
talvasconcelos May 4, 2026
34e6e4e
settle tab from tpos
talvasconcelos May 4, 2026
5b34c04
fix: linting on tests
talvasconcelos May 5, 2026
1f7dca4
fix: deprecated uv dev depencies
talvasconcelos May 5, 2026
5721aa9
more tests
talvasconcelos May 5, 2026
0a58937
fix: null `wallet` could break tpos on PUT
talvasconcelos May 5, 2026
fc918e0
fix: pass tabs error msg to tpos
talvasconcelos Jun 10, 2026
a556db4
rebase
talvasconcelos Jun 15, 2026
41e6b2f
Merge add tabs integration into TPoS refactor branch
talvasconcelos Jul 6, 2026
78066cf
test: cover TPoS API endpoints
talvasconcelos Jul 6, 2026
a1903b7
refactor: move tabs endpoints out of TPoS API
talvasconcelos Jul 6, 2026
5c3b153
refactor: move inventory endpoints out of TPoS API
talvasconcelos Jul 6, 2026
37322f3
refactor: move onchain endpoint out of TPoS API
talvasconcelos Jul 6, 2026
5a6332a
refactor: move wrapper endpoints out of TPoS API
talvasconcelos Jul 6, 2026
32064fb
refactor: move invoice action endpoints out of TPoS API
talvasconcelos Jul 6, 2026
a9868ed
refactor: move invoice creation endpoint out of TPoS API
talvasconcelos Jul 6, 2026
bdbe8c0
test: cover TPoS payment smoke paths
talvasconcelos Jul 6, 2026
0de981f
fix: settle cash invoices immediately
talvasconcelos Jul 6, 2026
944a9b2
Revert "fix: settle cash invoices immediately"
talvasconcelos Jul 6, 2026
e233038
fix: mark cash invoices paid before dispatch
talvasconcelos Jul 6, 2026
2f2ac8a
fix: mark onchain invoices paid before dispatch
talvasconcelos Jul 6, 2026
31a558b
refactor: move internal token helper to helpers.py
talvasconcelos Jul 6, 2026
afdf728
refactor: split wrapper services into services_wrapper.py
talvasconcelos Jul 6, 2026
28a7b3b
refactor: split inventory services into services_inventory.py
talvasconcelos Jul 6, 2026
32339ec
refactor: split onchain services into services_onchain.py
talvasconcelos Jul 6, 2026
b0aaf69
refactor: split tabs services into services_tabs.py
talvasconcelos Jul 6, 2026
b32007e
refactor: split orders services into services_orders.py
talvasconcelos Jul 6, 2026
b6ec426
fix: requeue settled tpos invoices
talvasconcelos Jul 8, 2026
fe02d7d
refactor: extract tpos frontend components
talvasconcelos Jul 8, 2026
3cb32fb
fix: round lnaddress payouts to sats
talvasconcelos Jul 8, 2026
f3bc8ad
fix: keep tpos lnaddress selection
talvasconcelos Jul 8, 2026
f454949
fix: restore tpos mounted hook
talvasconcelos Jul 8, 2026
d9df547
revert: keep lnaddress button unchanged
talvasconcelos Jul 8, 2026
5befecd
fix: send fiat tip amount to remote tpos
talvasconcelos Jul 8, 2026
087d555
fix: use fiat tip in remote invoice UI
talvasconcelos Jul 8, 2026
f64ef42
notify on nfc error
talvasconcelos Jul 21, 2026
4a2ead2
final review
talvasconcelos Jul 21, 2026
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ __pycache__
node_modules
.mypy_cache
.venv

.codex
5 changes: 5 additions & 0 deletions helpers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json

from lnbits.helpers import create_access_token
from loguru import logger


Expand Down Expand Up @@ -64,3 +65,7 @@ def normalize_image(val: str | None) -> str | None:
if val.startswith("http") or val.startswith("/api/") or val.startswith("data:"):
return val
return f"/api/v1/assets/{val}/thumbnail"


def create_internal_user_access_token(user_id: str) -> str:
return create_access_token({"sub": "", "usr": user_id}, token_expire_minutes=1)
12 changes: 12 additions & 0 deletions migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,3 +312,15 @@ async def m024_add_assetlinks_cache(db: Database):
updated_at INTEGER NOT NULL DEFAULT 0
);
""")


async def m025_add_tabs_integration_settings(db: Database):
"""
Add tabs integration settings.
"""
await db.execute("""
ALTER TABLE tpos.pos ADD tabs_enabled BOOLEAN DEFAULT false;
""")
await db.execute("""
ALTER TABLE tpos.pos ADD tabs_allow_create BOOLEAN DEFAULT false;
""")
46 changes: 46 additions & 0 deletions models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ class CreateWithdrawPay(BaseModel):
pay_link: str


class CreateTposInvoiceTabSettlement(BaseModel):
tab_id: str = Field(..., min_length=1)
amount: float = Field(..., gt=0)
reference: str | None = Field(None, max_length=120)
description: str | None = Field(None, max_length=512)
idempotency_key: str = Field(..., min_length=8, max_length=128)


class CreateTposInvoice(BaseModel):
amount: int = Query(..., ge=1)
memo: str | None = Query(None)
Expand All @@ -31,6 +39,7 @@ class CreateTposInvoice(BaseModel):
payment_method: str | None = Query(None)
amount_fiat: float | None = Query(None, ge=0.0)
tip_amount_fiat: float | None = Query(None, ge=0.0)
tab_settlement: CreateTposInvoiceTabSettlement | None = Query(None)


class InventorySaleItem(BaseModel):
Expand Down Expand Up @@ -77,6 +86,8 @@ class CreateTposData(BaseModel):
onchain_enabled: bool = Field(False)
onchain_wallet_id: str | None = None
onchain_zero_conf: bool = Field(True)
tabs_enabled: bool = Field(False)
tabs_allow_create: bool = Field(False)

@validator("tax_default", pre=True, always=True)
def default_tax_when_none(cls, v):
Expand Down Expand Up @@ -117,6 +128,8 @@ class TposClean(BaseModel):
onchain_enabled: bool = False
onchain_wallet_id: str | None = None
onchain_zero_conf: bool = True
tabs_enabled: bool = False
tabs_allow_create: bool = False

@property
def withdraw_maximum(self) -> int:
Expand Down Expand Up @@ -170,6 +183,39 @@ class TposInvoiceResponse(BaseModel):
extra: dict[str, Any] = Field(default_factory=dict)


class TposTab(BaseModel):
id: str
name: str
customer_name: str | None = None
reference: str | None = None
currency: str = "sats"
status: str = "open"
balance: float = 0
is_archived: bool = False


class TposTabList(BaseModel):
data: list[TposTab] = Field(default_factory=list)


class CreateTposTabData(BaseModel):
name: str = Field(..., min_length=1, max_length=120)
customer_name: str | None = None
reference: str | None = None
currency: str | None = None
limit_type: str = "none"
limit_amount: float | None = None


class CreateTposTabCharge(BaseModel):
amount: float = Field(..., gt=0)
description: str | None = Field(None, max_length=512)
items: list[dict[str, Any]] = Field(default_factory=list, max_items=200)
notes: dict[str, Any] | None = None
internal_memo: str | None = Field(None, max_length=512)
idempotency_key: str = Field(..., min_length=8, max_length=128)


class LnurlCharge(BaseModel):
id: str
tpos_id: str
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ authors = [{ name = "Alan Bits", email = "alan@lnbits.com" }]
urls = { Homepage = "https://lnbits.com", Repository = "https://github.com/lnbits/tpos" }
dependencies = [ "lnbits>1" ]

[tool.uv]
dev-dependencies = [
[dependency-groups]
dev = [
"black",
"pytest-asyncio",
"pytest",
Expand Down
Loading
Loading