Skip to content

Commit 24faa1a

Browse files
committed
feat: fork boltcards as TagID extension
- Rename extension ID: boltcards -> tagid - Rename all routes, DB prefix, router names, template paths - Update config.json and manifest.json for AxelHamburch/tagid_extension - Add README in zapbox-extension style with feature documentation Includes upstream features: - feat: PIN limit protection per card (4-digit PIN, PBKDF2-SHA256 hash, auto-disable after 3 wrong attempts) [feature/pin-limit] - fix: failed payments no longer count towards the daily limit [fix/daily-limit-failed-payments]
1 parent 88a88cf commit 24faa1a

18 files changed

Lines changed: 178 additions & 142 deletions

README.md

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,35 @@
1-
# Bolt Cards - <small>[LNbits](https://github.com/lnbits/lnbits) extension</small>
1+
# TagID Extension - <small>[LNbits](https://github.com/lnbits/lnbits) extension</small>
2+
3+
> **Forked from [lnbits/boltcards](https://github.com/lnbits/boltcards)**
4+
> Extended with PIN limit protection and failed-payment daily-limit fix.
5+
6+
Self custody NFC Bolt Cards with one-time LNURLw links — now with optional PIN verification and accurate daily spend tracking.
7+
8+
Check out [lnbits.com](https://lnbits.com) & join the Telegram support group [Makerbits](https://t.me/makerbits)
9+
10+
`Original authors: dni, prusnak, talvasconcelos, arbadacarbaYK, gorrdy, arcbtc` / `TagID extension: AxelHamburch`
11+
12+
Extension manifest source for LNbits: [https://raw.githubusercontent.com/AxelHamburch/tagid_extension/main/manifest.json](https://raw.githubusercontent.com/AxelHamburch/tagid_extension/main/manifest.json)
13+
14+
---
15+
16+
## Added Features
17+
18+
### PIN Limit (optional per-card PIN protection)
19+
20+
- Set a **PIN threshold (sat)**: any withdrawal at or above this amount requires the card holder to enter a 4-digit PIN.
21+
- The PIN is stored as a salted PBKDF2-SHA256 hash — never in plaintext.
22+
- After **3 wrong PIN attempts** across taps the card is automatically **disabled** and must be re-enabled by the wallet owner.
23+
- Attempt counter resets when the card is re-enabled or when a correct PIN is entered.
24+
25+
### Failed-Payment Daily Limit Fix
26+
27+
- Limit checks (tx limit & daily limit) now happen **before** the hit is marked as spent, so a rejected payment does not consume the daily budget.
28+
- When a payment fails after the invoice was accepted, the hit amount is zeroed so it does not count towards the daily limit.
29+
30+
---
31+
32+
233

334
<small>For more about LNBits extensions check [this tutorial](https://youtu.be/_sW7miqaXJc)</small>
435

@@ -74,14 +105,14 @@ The key #00, K0 (also know as auth key) is used as authentification key. It is n
74105
There's also a more [advanced guide](https://www.whitewolftech.com/articles/payment-card/) to set cards up manually with a card reader connected to your computer.
75106
Writing can also be done (without setting the keys) via the [TagWriter app by NXP](https://play.google.com/store/apps/details?id=com.nxp.nfc.tagwriter) on Android.
76107

77-
The URI should be `lnurlw://YOUR_LNBITS_DOMAIN/boltcards/api/v1/scan/{YOUR_card_external_id}?p=00000000000000000000000000000000&c=0000000000000000`
108+
The URI should be `lnurlw://YOUR_LNBITS_DOMAIN/tagid/api/v1/scan/{YOUR_card_external_id}?p=00000000000000000000000000000000&c=0000000000000000`
78109

79110
Then fill up the card parameters in the extension. Card Auth key (K0) can be filled in the extension just for the record. Initical counter can be 0.
80111

81112
- If you don't know the card ID, use NXP TagInfo app to read it first.
82113
- Tap Write tags > New Data Set > Link
83114
- Set URI type to Custom URL
84-
- URL should look like `lnurlw://YOUR_LNBITS_DOMAIN/boltcards/api/v1/scan/{YOUR_card_external_id}?p=00000000000000000000000000000000&c=0000000000000000`
115+
- URL should look like `lnurlw://YOUR_LNBITS_DOMAIN/tagid/api/v1/scan/{YOUR_card_external_id}?p=00000000000000000000000000000000&c=0000000000000000`
85116
- click Configure mirroring options
86117
- Select Card Type NTAG 424 DNA
87118
- Check Enable SDM Mirroring

__init__.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,48 @@
1-
import asyncio
1+
import asyncio
22

33
from fastapi import APIRouter
44
from loguru import logger
55

66
from .crud import db
77
from .tasks import wait_for_paid_invoices
8-
from .views import boltcards_generic_router
9-
from .views_api import boltcards_api_router
10-
from .views_lnurl import boltcards_lnurl_router
8+
from .views import tagid_generic_router
9+
from .views_api import tagid_api_router
10+
from .views_lnurl import tagid_lnurl_router
1111

12-
boltcards_static_files = [
12+
tagid_static_files = [
1313
{
14-
"path": "/boltcards/static",
15-
"name": "boltcards_static",
14+
"path": "/tagid/static",
15+
"name": "tagid_static",
1616
}
1717
]
1818

19-
boltcards_ext: APIRouter = APIRouter(prefix="/boltcards", tags=["boltcards"])
20-
boltcards_ext.include_router(boltcards_generic_router)
21-
boltcards_ext.include_router(boltcards_api_router)
22-
boltcards_ext.include_router(boltcards_lnurl_router)
19+
tagid_ext: APIRouter = APIRouter(prefix="/tagid", tags=["tagid"])
20+
tagid_ext.include_router(tagid_generic_router)
21+
tagid_ext.include_router(tagid_api_router)
22+
tagid_ext.include_router(tagid_lnurl_router)
2323

2424
scheduled_tasks: list[asyncio.Task] = []
2525

2626

27-
def boltcards_stop():
27+
def tagid_stop():
2828
for task in scheduled_tasks:
2929
try:
3030
task.cancel()
3131
except Exception as ex:
3232
logger.warning(ex)
3333

3434

35-
def boltcards_start():
35+
def tagid_start():
3636
from lnbits.tasks import create_permanent_unique_task
3737

38-
task = create_permanent_unique_task("ext_boltcards", wait_for_paid_invoices)
38+
task = create_permanent_unique_task("ext_tagid", wait_for_paid_invoices)
3939
scheduled_tasks.append(task)
4040

4141

4242
__all__ = [
43-
"boltcards_ext",
44-
"boltcards_start",
45-
"boltcards_static_files",
46-
"boltcards_stop",
43+
"tagid_ext",
44+
"tagid_start",
45+
"tagid_static_files",
46+
"tagid_stop",
4747
"db",
4848
]

config.json

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
{
2-
"name": "Bolt Cards",
3-
"short_description": "Self custody Bolt Cards with one time LNURLw",
4-
"tile": "/boltcards/static/image/boltcard.png",
2+
"name": "TagID",
3+
"short_description": "Self custody NFC Bolt Cards with one time LNURLw — with PIN limit and daily limit fixes",
4+
"tile": "/tagid/static/image/boltcard.png",
55
"version": "1.1.0",
66
"min_lnbits_version": "1.3.0",
77
"contributors": [
8+
{
9+
"name": "AxelHamburch",
10+
"uri": "https://github.com/AxelHamburch",
11+
"role": "Developer"
12+
},
813
{
914
"name": "dni",
1015
"uri": "https://github.com/dni",
@@ -53,21 +58,21 @@
5358
],
5459
"images": [
5560
{
56-
"uri": "https://raw.githubusercontent.com/lnbits/boltcards/main/static/image/1.jpg",
61+
"uri": "https://raw.githubusercontent.com/AxelHamburch/tagid_extension/main/static/image/1.jpg",
5762
"link": "https://www.youtube.com/embed/_sW7miqaXJc?si=UlFX7yU2A_LkC70r"
5863
},
5964
{
60-
"uri": "https://raw.githubusercontent.com/lnbits/boltcards/main/static/image/2.jpg",
65+
"uri": "https://raw.githubusercontent.com/AxelHamburch/tagid_extension/main/static/image/2.jpg",
6166
"link": "https://www.youtube.com/embed/wJ7QLFTRjK0?si=DRNH9ycKZrCLjFcx"
6267
},
6368
{
64-
"uri": "https://raw.githubusercontent.com/lnbits/boltcards/main/static/image/1.png"
69+
"uri": "https://raw.githubusercontent.com/AxelHamburch/tagid_extension/main/static/image/1.png"
6570
},
6671
{
67-
"uri": "https://raw.githubusercontent.com/lnbits/boltcards/main/static/image/3.jpg"
72+
"uri": "https://raw.githubusercontent.com/AxelHamburch/tagid_extension/main/static/image/3.jpg"
6873
}
6974
],
70-
"description_md": "https://raw.githubusercontent.com/lnbits/boltcards/main/description.md",
71-
"terms_and_conditions_md": "https://raw.githubusercontent.com/lnbits/boltcards/main/toc.md",
75+
"description_md": "https://raw.githubusercontent.com/AxelHamburch/tagid_extension/main/description.md",
76+
"terms_and_conditions_md": "https://raw.githubusercontent.com/AxelHamburch/tagid_extension/main/toc.md",
7277
"license": "MIT"
7378
}

0 commit comments

Comments
 (0)