Skip to content

Commit 1a2f37a

Browse files
authored
Merge pull request #5 from DoktorShift/update_v1
Fix LNURL callback - accept amount parameter from wallets info modal enhancements
2 parents 8f03ec1 + aed94e8 commit 1a2f37a

File tree

3 files changed

+355
-97
lines changed

3 files changed

+355
-97
lines changed

lnurl.py

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -109,23 +109,18 @@ async def lnurl_params(request: Request, device_id: str, switch_id: str):
109109
async def lnurl_callback(
110110
request: Request,
111111
paymentid: str,
112-
pr: str = Query(None),
113-
k1: str = Query(None),
112+
amount: int = Query(..., description="Amount in millisatoshis"),
114113
):
115114
payment = await get_payment(paymentid)
116115
if not payment:
117-
raise HTTPException(
118-
status_code=HTTPStatus.NOT_FOUND, detail="payment not found."
119-
)
116+
return {"status": "ERROR", "reason": "Payment not found."}
120117

121118
if payment.payhash == "used":
122119
return {"status": "ERROR", "reason": "Payment already used."}
123120

124121
device = await get_device(payment.deviceid)
125122
if not device:
126-
raise HTTPException(
127-
status_code=HTTPStatus.NOT_FOUND, detail="device not found."
128-
)
123+
return {"status": "ERROR", "reason": "Device not found."}
129124

130125
switch = None
131126
for _switch in device.switches:
@@ -134,32 +129,37 @@ async def lnurl_callback(
134129
break
135130

136131
if not switch:
137-
raise HTTPException(
138-
status_code=HTTPStatus.NOT_FOUND, detail="device switch not found."
132+
return {"status": "ERROR", "reason": "Switch not found."}
133+
134+
# Validate amount matches expected
135+
if amount != payment.sats:
136+
return {"status": "ERROR", "reason": f"Amount mismatch. Expected {payment.sats} msats."}
137+
138+
try:
139+
payment_hash, payment_request = await create_invoice(
140+
wallet_id=device.wallet,
141+
amount=int(amount / 1000),
142+
memo=create_payment_memo(device, switch),
143+
unhashed_description=json.dumps(
144+
[["text/plain", create_payment_memo(device, switch)]]
145+
).encode(),
146+
extra={
147+
"tag": "DeviceTimer",
148+
"Device": device.id,
149+
"Switch": switch.id,
150+
"amount": switch.amount,
151+
"currency": device.currency,
152+
"id": paymentid,
153+
"received": False,
154+
"fulfilled": False,
155+
},
139156
)
140157

141-
payment_hash, payment_request = await create_invoice(
142-
wallet_id=device.wallet,
143-
amount=int(payment.sats / 1000),
144-
memo=create_payment_memo(device, switch),
145-
unhashed_description=json.dumps(
146-
[["text/plain", create_payment_memo(device, switch)]]
147-
).encode(),
148-
extra={
149-
"tag": "DeviceTimer",
150-
"Device": device.id,
151-
"Switch": switch.id,
152-
"amount": switch.amount,
153-
"currency": device.currency,
154-
"id": paymentid,
155-
"received": False,
156-
"fulfilled": False,
157-
},
158-
)
159-
160-
await update_payment(payment_id=paymentid, payhash=payment_hash)
158+
await update_payment(payment_id=paymentid, payhash=payment_hash)
161159

162-
return {
163-
"pr": payment_request,
164-
"routes": [],
165-
}
160+
return {
161+
"pr": payment_request,
162+
"routes": [],
163+
}
164+
except Exception as e:
165+
return {"status": "ERROR", "reason": str(e)}

static/js/index.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,40 @@ window.app = Vue.createApp({
7979
switchCount: 0
8080
},
8181

82+
donationDialog: {
83+
show: false,
84+
address: 'u60311@blink.sv',
85+
message: 'DeviceTimer extension donation',
86+
selectedTier: null,
87+
customAmount: null,
88+
tiers: [
89+
{
90+
amount: 5000,
91+
label: 'Coffee',
92+
icon: 'local_cafe',
93+
description: 'Buy us a coffee or sponsor us to keep us building new extensions'
94+
},
95+
{
96+
amount: 50000,
97+
label: 'Supporter',
98+
icon: 'thumb_up',
99+
description: 'Help cover server costs and testing hardware'
100+
},
101+
{
102+
amount: 210000,
103+
label: 'Believer',
104+
icon: 'volunteer_activism',
105+
description: 'Generous support for ongoing open source development'
106+
},
107+
{
108+
amount: 1000000,
109+
label: 'Sponsor',
110+
icon: 'rocket_launch',
111+
description: 'Fund the development of a brand new extension'
112+
}
113+
]
114+
},
115+
82116
drawerRight: false
83117
}
84118
},
@@ -421,6 +455,49 @@ window.app = Vue.createApp({
421455
window.open('https://github.com/DoktorShift/DeviceTimer', '_blank')
422456
},
423457

458+
openDonationDialog() {
459+
this.donationDialog.selectedTier = this.donationDialog.tiers[0]
460+
this.donationDialog.customAmount = null
461+
this.donationDialog.show = true
462+
},
463+
464+
selectDonationTier(tier) {
465+
this.donationDialog.selectedTier = tier
466+
this.donationDialog.customAmount = null
467+
},
468+
469+
selectCustomAmount() {
470+
this.donationDialog.selectedTier = null
471+
},
472+
473+
getDonationAmount() {
474+
if (this.donationDialog.selectedTier) {
475+
return this.donationDialog.selectedTier.amount
476+
}
477+
return this.donationDialog.customAmount || 0
478+
},
479+
480+
getDonationQrUrl() {
481+
const amount = this.getDonationAmount()
482+
const address = this.donationDialog.address
483+
if (amount > 0) {
484+
return 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=' +
485+
encodeURIComponent('lightning:' + address + '?amount=' + (amount * 1000))
486+
}
487+
return 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=' +
488+
encodeURIComponent('lightning:' + address)
489+
},
490+
491+
formatSats(amount) {
492+
if (amount >= 1000000) {
493+
return (amount / 1000000).toFixed(1).replace(/\.0$/, '') + 'M'
494+
}
495+
if (amount >= 1000) {
496+
return (amount / 1000).toFixed(0) + 'k'
497+
}
498+
return amount.toString()
499+
},
500+
424501
isDeviceLive(deviceId) {
425502
return this.activeWebsocketDeviceId === deviceId && this.activeWebsocket !== null
426503
}

0 commit comments

Comments
 (0)