diff --git a/models.py b/models.py
index ca744cb..59d800e 100644
--- a/models.py
+++ b/models.py
@@ -5,7 +5,7 @@
from lnurl import Lnurl
from lnurl import encode as lnurl_encode
from lnurl.types import LnurlPayMetadata
-from pydantic import BaseModel
+from pydantic import BaseModel, Field
ZERO_KEY = "00000000000000000000000000000000"
@@ -71,3 +71,8 @@ class Refund(BaseModel):
hit_id: str
refund_amount: int
time: datetime
+
+
+class UIDPost(BaseModel):
+ UID: str = Field(None, description="The UID of the card.")
+ LNURLW: str = Field(None, description="The LNURLW of the card.")
diff --git a/static/js/index.js b/static/js/index.js
index 2208189..b553347 100644
--- a/static/js/index.js
+++ b/static/js/index.js
@@ -148,6 +148,15 @@ window.app = Vue.createApp({
}
}
},
+ computed: {
+ deeplinkUrl() {
+ const baseUrl = `boltcard://${this.qrCodeDialog.wipe ? 'reset' : 'program'}`
+ const url =
+ this.qrCodeDialog.data.link +
+ (this.qrCodeDialog.wipe ? '&wipe=true' : '')
+ return `${baseUrl}?url=${encodeURIComponent(url)}`
+ }
+ },
methods: {
readNfcTag() {
const ndef = new NDEFReader()
@@ -229,6 +238,9 @@ window.app = Vue.createApp({
this.qrCodeDialog.data = {
id: card.id,
link: window.location.origin + '/boltcards/api/v1/auth?a=' + card.otp,
+ encodedURI: encodeURIComponent(
+ window.location.origin + '/boltcards/api/v1/auth?a=' + card.otp
+ ),
name: card.card_name,
uid: card.uid,
external_id: card.external_id,
diff --git a/templates/boltcards/index.html b/templates/boltcards/index.html
index 838eefb..cd63021 100644
--- a/templates/boltcards/index.html
+++ b/templates/boltcards/index.html
@@ -463,6 +463,7 @@
Click to copy, then paste to NFC Card Creator
>
Backup the keys, or wipe the card first!
+
+ Use Boltcard Programmer App
+
Close
diff --git a/views_lnurl.py b/views_lnurl.py
index f4a39b1..01da89e 100644
--- a/views_lnurl.py
+++ b/views_lnurl.py
@@ -16,12 +16,14 @@
get_card,
get_card_by_external_id,
get_card_by_otp,
+ get_card_by_uid,
get_hit,
get_hits_today,
spend_hit,
update_card_counter,
update_card_otp,
)
+from .models import UIDPost
from .nxp424 import decrypt_sun, get_sun_mac
boltcards_lnurl_router = APIRouter()
@@ -179,6 +181,46 @@ async def api_auth(a, request: Request):
return response
+# /boltcards/api/v1/auth?a=00000000000000000000000000000000
+@boltcards_lnurl_router.post("/api/v1/auth")
+async def api_auth_post(a: str, request: Request, data: UIDPost, wipe: bool = False):
+ card = None
+ if wipe:
+ card = await get_card_by_otp(a)
+ else:
+ if not data.UID:
+ raise HTTPException(
+ detail="Missing UID.", status_code=HTTPStatus.BAD_REQUEST
+ )
+
+ card = await get_card_by_uid(data.UID)
+ if not card:
+ raise HTTPException(
+ detail="Card does not exist.", status_code=HTTPStatus.NOT_FOUND
+ )
+ new_otp = secrets.token_hex(16)
+ await update_card_otp(new_otp, card.id)
+ lnurlw_base = (
+ f"{urlparse(str(request.url)).netloc}/boltcards/api/v1/scan/{card.external_id}"
+ )
+ response = {
+ "CARD_NAME": card.card_name,
+ "ID": str(1),
+ "K0": card.k0,
+ "K1": card.k1,
+ "K2": card.k2,
+ "K3": card.k1,
+ "K4": card.k2,
+ "LNURLW_BASE": "LNURLW://" + lnurlw_base,
+ "LNURLW": "LNURLW://" + lnurlw_base,
+ "PROTOCOL_NAME": "NEW_BOLT_CARD_RESPONSE",
+ "PROTOCOL_VERSION": str(1),
+ }
+ if wipe:
+ response["action"] = "wipe"
+ return response
+
+
###############LNURLPAY REFUNDS#################