Extension: LNURLw webhook_url (#610)

* LNURLw web_hook

* crlf -> lf

* Fix typo

* LNURLw webhook api doc
This commit is contained in:
Tomas Bezouska 2022-06-01 15:24:17 +02:00 committed by GitHub
parent 7c4ce9bf96
commit 895d9d2e0a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 54 additions and 7 deletions

View file

@ -25,9 +25,10 @@ async def create_withdraw_link(
unique_hash,
k1,
open_time,
usescsv
usescsv,
webhook_url
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(
link_id,
@ -42,6 +43,7 @@ async def create_withdraw_link(
urlsafe_short_hash(),
int(datetime.now().timestamp()) + data.wait_time,
usescsv,
data.webhook_url
),
)
link = await get_withdraw_link(link_id, 0)

View file

@ -1,4 +1,7 @@
import json
import traceback
import httpx
from datetime import datetime
from http import HTTPStatus
@ -103,17 +106,35 @@ async def api_lnurl_callback(
await update_withdraw_link(link.id, **changes)
payment_request = pr
await pay_invoice(
payment_hash = await pay_invoice(
wallet_id=link.wallet,
payment_request=payment_request,
max_sat=link.max_withdrawable,
extra={"tag": "withdraw"},
)
if link.webhook_url:
async with httpx.AsyncClient() as client:
try:
r = await client.post(
link.webhook_url,
json={
"payment_hash": payment_hash,
"payment_request": payment_request,
"lnurlw": link.id,
},
timeout=40,
)
except Exception as exc:
# webhook fails shouldn't cause the lnurlw to fail since invoice is already paid
print("Caught exception when dispatching webhook url:", exc)
return {"status": "OK"}
except Exception as e:
await update_withdraw_link(link.id, **changesback)
print(traceback.format_exc())
return {"status": "ERROR", "reason": "Link not working"}

View file

@ -108,3 +108,9 @@ async def m003_make_hash_check(db):
);
"""
)
async def m004_webhook_url(db):
"""
Adds webhook_url
"""
await db.execute("ALTER TABLE withdraw.withdraw_link ADD COLUMN webhook_url TEXT;")

View file

@ -15,6 +15,7 @@ class CreateWithdrawData(BaseModel):
uses: int = Query(..., ge=1)
wait_time: int = Query(..., ge=1)
is_unique: bool
webhook_url: str = Query(None)
class WithdrawLink(BaseModel):
@ -32,6 +33,7 @@ class WithdrawLink(BaseModel):
used: int = Query(0)
usescsv: str = Query(None)
number: int = Query(0)
webhook_url: str = Query(None)
@property
def is_spent(self) -> bool:

View file

@ -179,7 +179,8 @@ new Vue({
'max_withdrawable',
'uses',
'wait_time',
'is_unique'
'is_unique',
'webhook_url'
)
)
.then(function (response) {

View file

@ -70,7 +70,8 @@
<code
>{"title": &lt;string&gt;, "min_withdrawable": &lt;integer&gt;,
"max_withdrawable": &lt;integer&gt;, "uses": &lt;integer&gt;,
"wait_time": &lt;integer&gt;, "is_unique": &lt;boolean&gt;}</code
"wait_time": &lt;integer&gt;, "is_unique": &lt;boolean&gt;,
"webhook_url": &lt;string&gt;}</code
>
<h5 class="text-caption q-mt-sm q-mb-none">
Returns 201 CREATED (application/json)
@ -81,7 +82,7 @@
>curl -X POST {{ request.base_url }}withdraw/api/v1/links -d '{"title":
&lt;string&gt;, "min_withdrawable": &lt;integer&gt;,
"max_withdrawable": &lt;integer&gt;, "uses": &lt;integer&gt;,
"wait_time": &lt;integer&gt;, "is_unique": &lt;boolean&gt;}' -H
"wait_time": &lt;integer&gt;, "is_unique": &lt;boolean&gt;, "webhook_url": &lt;string&gt;}' -H
"Content-type: application/json" -H "X-Api-Key: {{
user.wallets[0].adminkey }}"
</code>

View file

@ -29,6 +29,7 @@
{{ col.label }}
</q-th>
<q-th auto-width></q-th>
<q-th auto-width></q-th>
</q-tr>
</template>
<template v-slot:body="props">
@ -81,6 +82,11 @@
<q-td v-for="col in props.cols" :key="col.name" :props="props">
{{ col.value }}
</q-td>
<q-td>
<q-icon v-if="props.row.webhook_url" size="14px" name="http">
<q-tooltip>Webhook to {{ props.row.webhook_url}}</q-tooltip>
</q-icon>
</q-td>
<q-td auto-width>
<q-btn
flat
@ -143,6 +149,14 @@
</q-select>
</div>
</div>
<q-input
filled
dense
v-model="formDialog.data.webhook_url"
type="text"
label="Webhook URL (optional)"
hint="A URL to be called whenever this link gets used."
></q-input>
<q-list>
<q-item tag="label" class="rounded-borders">
<q-item-section avatar>