Fixed some lnticket bugs

This commit is contained in:
benarc 2020-11-30 14:02:17 +00:00
parent 409f62dee7
commit 67e8c567a3
6 changed files with 91 additions and 29 deletions

View file

@ -46,7 +46,7 @@ async def set_ticket_paid(payment_hash: str) -> Tickets:
amount = formdata.amountmade + row[7] amount = formdata.amountmade + row[7]
await db.execute( await db.execute(
""" """
UPDATE forms UPDATE form
SET amountmade = ? SET amountmade = ?
WHERE id = ? WHERE id = ?
""", """,
@ -80,14 +80,14 @@ async def delete_ticket(ticket_id: str) -> None:
# FORMS # FORMS
async def create_form(*, wallet: str, name: str, description: str, costpword: int) -> Forms: async def create_form(*, wallet: str, name: str, webhook: Optional[str] = None, description: str, costpword: int) -> Forms:
form_id = urlsafe_short_hash() form_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO forms (id, wallet, name, description, costpword, amountmade) INSERT INTO form (id, wallet, name, webhook, description, costpword, amountmade)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?)
""", """,
(form_id, wallet, name, description, costpword, 0), (form_id, wallet, name, webhook, description, costpword, 0),
) )
form = await get_form(form_id) form = await get_form(form_id)
@ -97,14 +97,14 @@ async def create_form(*, wallet: str, name: str, description: str, costpword: in
async def update_form(form_id: str, **kwargs) -> Forms: async def update_form(form_id: str, **kwargs) -> Forms:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute(f"UPDATE forms SET {q} WHERE id = ?", (*kwargs.values(), form_id)) await db.execute(f"UPDATE form SET {q} WHERE id = ?", (*kwargs.values(), form_id))
row = await db.fetchone("SELECT * FROM forms WHERE id = ?", (form_id,)) row = await db.fetchone("SELECT * FROM form WHERE id = ?", (form_id,))
assert row, "Newly updated form couldn't be retrieved" assert row, "Newly updated form couldn't be retrieved"
return Forms(**row) return Forms(**row)
async def get_form(form_id: str) -> Optional[Forms]: async def get_form(form_id: str) -> Optional[Forms]:
row = await db.fetchone("SELECT * FROM forms WHERE id = ?", (form_id,)) row = await db.fetchone("SELECT * FROM form WHERE id = ?", (form_id,))
return Forms(**row) if row else None return Forms(**row) if row else None
@ -113,10 +113,10 @@ async def get_forms(wallet_ids: Union[str, List[str]]) -> List[Forms]:
wallet_ids = [wallet_ids] wallet_ids = [wallet_ids]
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall(f"SELECT * FROM forms WHERE wallet IN ({q})", (*wallet_ids,)) rows = await db.fetchall(f"SELECT * FROM form WHERE wallet IN ({q})", (*wallet_ids,))
return [Forms(**row) for row in rows] return [Forms(**row) for row in rows]
async def delete_form(form_id: str) -> None: async def delete_form(form_id: str) -> None:
await db.execute("DELETE FROM forms WHERE id = ?", (form_id,)) await db.execute("DELETE FROM form WHERE id = ?", (form_id,))

View file

@ -83,3 +83,56 @@ async def m002_changed(db):
), ),
) )
await db.execute("DROP TABLE tickets") await db.execute("DROP TABLE tickets")
async def m003_changed(db):
await db.execute(
"""
CREATE TABLE IF NOT EXISTS form (
id TEXT PRIMARY KEY,
wallet TEXT NOT NULL,
name TEXT NOT NULL,
webhook TEXT,
description TEXT NOT NULL,
costpword INTEGER NOT NULL,
amountmade INTEGER NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now'))
);
"""
)
for row in [list(row) for row in await db.fetchall("SELECT * FROM forms")]:
usescsv = ""
for i in range(row[5]):
if row[7]:
usescsv += "," + str(i + 1)
else:
usescsv += "," + str(1)
usescsv = usescsv[1:]
await db.execute(
"""
INSERT INTO form (
id,
wallet,
name,
webhook,
description,
costpword,
amountmade
)
VALUES (?, ?, ?, ?, ?, ?, ?)
""",
(
row[0],
row[1],
row[2],
row[3],
row[4],
row[5],
row[6],
),
)
await db.execute("DROP TABLE forms")

View file

@ -5,6 +5,7 @@ class Forms(NamedTuple):
id: str id: str
wallet: str wallet: str
name: str name: str
webhook: str
description: str description: str
costpword: int costpword: int
amountmade: int amountmade: int

View file

@ -113,6 +113,7 @@
if (sats === parseInt('{{ form_costpword }}')) { if (sats === parseInt('{{ form_costpword }}')) {
return '0 Sats to pay' return '0 Sats to pay'
} else { } else {
this.formDialog.data.sats = sats
return sats + ' Sats to pay' return sats + ' Sats to pay'
} }
} }
@ -140,7 +141,8 @@
form: '{{ form_id }}', form: '{{ form_id }}',
name: self.formDialog.data.name, name: self.formDialog.data.name,
email: self.formDialog.data.email, email: self.formDialog.data.email,
ltext: self.formDialog.data.text ltext: self.formDialog.data.text,
sats: self.formDialog.data.sats,
}) })
.then(function (response) { .then(function (response) {
self.paymentReq = response.data.payment_request self.paymentReq = response.data.payment_request
@ -162,12 +164,6 @@
.get('/lnticket/api/v1/tickets/' + self.paymentCheck) .get('/lnticket/api/v1/tickets/' + self.paymentCheck)
.then(function (res) { .then(function (res) {
if (res.data.paid) { if (res.data.paid) {
clearInterval(paymentChecker)
dismissMsg()
self.formDialog.data.name = ''
self.formDialog.data.email = ''
self.formDialog.data.text = ''
self.$q.notify({ self.$q.notify({
type: 'positive', type: 'positive',
message: 'Sent, thank you!', message: 'Sent, thank you!',
@ -178,12 +174,19 @@
status: 'complete', status: 'complete',
paymentReq: null paymentReq: null
} }
clearInterval(paymentChecker)
dismissMsg()
self.formDialog.data.name = ''
self.formDialog.data.email = ''
self.formDialog.data.text = ''
} }
}) })
.catch(function (error) { .catch(function (error) {
LNbits.utils.notifyApiError(error) LNbits.utils.notifyApiError(error)
}) })
}, 2000) }, 2000)
}) })
.catch(function (error) { .catch(function (error) {
LNbits.utils.notifyApiError(error) LNbits.utils.notifyApiError(error)

View file

@ -114,7 +114,7 @@
</q-tr> </q-tr>
</template> </template>
<template v-slot:body="props"> <template v-slot:body="props">
<q-tr :props="props"> <q-tr :props="props" v-if="props.row.paid">
<q-td auto-width> <q-td auto-width>
<q-btn <q-btn
unelevated unelevated
@ -181,6 +181,14 @@
type="name" type="name"
label="Form name " label="Form name "
></q-input> ></q-input>
<q-input
filled
dense
v-model.trim="formDialog.data.webhook"
type="text"
label="Webhook (optional)"
hint="A URL to be called whenever this link receives a payment."
></q-input>
<q-input <q-input
filled filled
dense dense
@ -244,6 +252,7 @@
{name: 'id', align: 'left', label: 'ID', field: 'id'}, {name: 'id', align: 'left', label: 'ID', field: 'id'},
{name: 'name', align: 'left', label: 'Name', field: 'name'}, {name: 'name', align: 'left', label: 'Name', field: 'name'},
{name: 'wallet', align: 'left', label: 'Wallet', field: 'wallet'}, {name: 'wallet', align: 'left', label: 'Wallet', field: 'wallet'},
{name: 'webhook', align: 'left', label: 'Webhook', field: 'webhook'},
{ {
name: 'description', name: 'description',
align: 'left', align: 'left',
@ -255,12 +264,6 @@
align: 'left', align: 'left',
label: 'Cost Per Word', label: 'Cost Per Word',
field: 'costpword' field: 'costpword'
},
{
name: 'amountmade',
align: 'left',
label: 'Amount Made',
field: 'amountmade'
} }
], ],
pagination: { pagination: {
@ -269,11 +272,11 @@
}, },
ticketsTable: { ticketsTable: {
columns: [ columns: [
{name: 'id', align: 'left', label: 'ID', field: 'id'}, {name: 'form', align: 'left', label: 'Form', field: 'form'},
{name: 'name', align: 'left', label: 'Name', field: 'name'}, {name: 'name', align: 'left', label: 'Name', field: 'name'},
{name: 'email', align: 'left', label: 'Email', field: 'email'}, {name: 'email', align: 'left', label: 'Email', field: 'email'},
{name: 'ltext', align: 'left', label: 'Ticket', field: 'ltext'}, {name: 'ltext', align: 'left', label: 'Ticket', field: 'ltext'},
{name: 'sats', align: 'left', label: 'Paid', field: 'sats'} {name: 'sats', align: 'left', label: 'Cost', field: 'sats'}
], ],
pagination: { pagination: {
rowsPerPage: 10 rowsPerPage: 10

View file

@ -42,6 +42,7 @@ async def api_forms():
schema={ schema={
"wallet": {"type": "string", "empty": False, "required": True}, "wallet": {"type": "string", "empty": False, "required": True},
"name": {"type": "string", "empty": False, "required": True}, "name": {"type": "string", "empty": False, "required": True},
"webhook": {"type": "string", "empty": False, "required": False},
"description": {"type": "string", "min": 0, "required": True}, "description": {"type": "string", "min": 0, "required": True},
"costpword": {"type": "integer", "min": 0, "required": True}, "costpword": {"type": "integer", "min": 0, "required": True},
} }
@ -99,6 +100,7 @@ async def api_tickets():
"name": {"type": "string", "empty": False, "required": True}, "name": {"type": "string", "empty": False, "required": True},
"email": {"type": "string", "empty": True, "required": True}, "email": {"type": "string", "empty": True, "required": True},
"ltext": {"type": "string", "empty": False, "required": True}, "ltext": {"type": "string", "empty": False, "required": True},
"sats": {"type": "integer", "min": 0, "required": True},
} }
) )
async def api_ticket_make_ticket(form_id): async def api_ticket_make_ticket(form_id):
@ -107,7 +109,7 @@ async def api_ticket_make_ticket(form_id):
return jsonify({"message": "LNTicket does not exist."}), HTTPStatus.NOT_FOUND return jsonify({"message": "LNTicket does not exist."}), HTTPStatus.NOT_FOUND
nwords = len(re.split(r"\s+", g.data["ltext"])) nwords = len(re.split(r"\s+", g.data["ltext"]))
sats = nwords * form.costpword sats = g.data["sats"]
payment_hash, payment_request = await create_invoice( payment_hash, payment_request = await create_invoice(
wallet_id=form.wallet, wallet_id=form.wallet,
amount=sats, amount=sats,
@ -115,7 +117,7 @@ async def api_ticket_make_ticket(form_id):
extra={"tag": "lnticket"}, extra={"tag": "lnticket"},
) )
ticket = await create_ticket(payment_hash=payment_hash, wallet=form.wallet, sats=sats, **g.data) ticket = await create_ticket(payment_hash=payment_hash, wallet=form.wallet, **g.data)
if not ticket: if not ticket:
return jsonify({"message": "LNTicket could not be fetched."}), HTTPStatus.NOT_FOUND return jsonify({"message": "LNTicket could not be fetched."}), HTTPStatus.NOT_FOUND
@ -130,7 +132,7 @@ async def api_ticket_send_ticket(payment_hash):
status = await check_invoice_status(ticket.wallet, payment_hash) status = await check_invoice_status(ticket.wallet, payment_hash)
is_paid = not status.pending is_paid = not status.pending
except Exception: except Exception:
return jsonify({"message": "Not paid."}), HTTPStatus.NOT_FOUND return jsonify({"paid": False}), HTTPStatus.OK
if is_paid: if is_paid:
wallet = await get_wallet(ticket.wallet) wallet = await get_wallet(ticket.wallet)