feat: add optional domain field (#120)
* feat: add optional domain field closes #119
This commit is contained in:
parent
76c5841bc8
commit
17135b45ae
8 changed files with 107 additions and 46 deletions
1
crud.py
1
crud.py
|
|
@ -65,6 +65,7 @@ async def create_pay_link(data: CreatePayLinkData) -> PayLink:
|
|||
created_at=now,
|
||||
updated_at=now,
|
||||
disposable=data.disposable if data.disposable is not None else True,
|
||||
domain=data.domain,
|
||||
)
|
||||
|
||||
await db.insert("lnurlp.pay_links", link)
|
||||
|
|
|
|||
|
|
@ -10,11 +10,16 @@ def parse_nostr_private_key(key: str) -> PrivateKey:
|
|||
return PrivateKey(bytes.fromhex(key))
|
||||
|
||||
|
||||
def lnurl_encode_link_id(req: Request, link_id: str) -> str:
|
||||
def lnurl_encode_link(req: Request, link_id: str, domain: str | None = None) -> str:
|
||||
if domain:
|
||||
url_str = f"https://{domain}/lnurlp/{link_id}"
|
||||
return str(lnurl_encode(url_str).bech32)
|
||||
|
||||
url = req.url_for("lnurlp.api_lnurl_response", link_id=link_id)
|
||||
url = url.replace(path=url.path)
|
||||
url_str = str(url)
|
||||
if url.netloc.endswith(".onion"):
|
||||
# change url string scheme to http
|
||||
url_str = url_str.replace("https://", "http://")
|
||||
|
||||
return str(lnurl_encode(url_str).bech32)
|
||||
|
|
|
|||
24
models.py
24
models.py
|
|
@ -35,6 +35,7 @@ class CreatePayLinkData(BaseModel):
|
|||
username: str | None = Query(None)
|
||||
zaps: bool | None = Query(False)
|
||||
disposable: bool | None = Query(True)
|
||||
domain: str | None = Query(None)
|
||||
|
||||
|
||||
class PayLink(BaseModel):
|
||||
|
|
@ -67,8 +68,25 @@ class PayLink(BaseModel):
|
|||
success_url: str | None = None
|
||||
currency: str | None = None
|
||||
fiat_base_multiplier: int | None = None
|
||||
|
||||
disposable: bool
|
||||
|
||||
# TODO deprecated, unused in the code, should be deleted from db.
|
||||
domain: str | None = None
|
||||
|
||||
|
||||
class PublicPayLink(BaseModel):
|
||||
id: str
|
||||
username: str | None = None
|
||||
description: str
|
||||
min: float
|
||||
max: float
|
||||
domain: str | None = None
|
||||
currency: str | None = None
|
||||
lnurl: str | None = Field(
|
||||
default=None,
|
||||
no_database=True,
|
||||
deprecated=True,
|
||||
description=(
|
||||
"Deprecated: Instead of using this bech32 encoded string, dynamically "
|
||||
"generate your own static link (lud17/bech32) on the client side. "
|
||||
"Example: lnurlp://${window.location.hostname}/lnurlp/${paylink_id}"
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,10 +2,26 @@ window.PageLnurlpPublic = {
|
|||
template: '#page-lnurlp-public',
|
||||
data() {
|
||||
return {
|
||||
url: ''
|
||||
url: '',
|
||||
payLink: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setUrl(link_id, domain) {
|
||||
this.url = `https://${domain || window.location.host}/lnurlp/${link_id}`
|
||||
},
|
||||
getPayLink() {
|
||||
this.api
|
||||
.request('GET', `/lnurlp/api/v1/links/public/${this.$route.params.id}`)
|
||||
.then(res => {
|
||||
this.payLink = res.data
|
||||
this.setUrl(this.payLink.id, this.payLink.domain)
|
||||
})
|
||||
.catch(this.utils.notifyApiError)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.url = window.location.origin + '/lnurlp/' + this.$route.params.id
|
||||
this.setUrl(this.$route.params.id)
|
||||
this.getPayLink()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ window.PageLnurlp = {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
lnaddress(link) {
|
||||
const domain = link.domain || window.location.host
|
||||
return `${link.username}@${domain}`
|
||||
},
|
||||
mapPayLink(obj) {
|
||||
const locationPath = [
|
||||
window.location.protocol,
|
||||
|
|
@ -140,11 +144,13 @@ window.PageLnurlp = {
|
|||
(link.success_url ? ' and URL "' + link.success_url + '"' : '')
|
||||
: 'do nothing',
|
||||
lnurl: link.lnurl,
|
||||
domain: link.domain,
|
||||
pay_url: link.pay_url,
|
||||
print_url: link.print_url,
|
||||
username: link.username
|
||||
}
|
||||
this.activeUrl = window.location.origin + '/lnurlp/' + link.id
|
||||
const domain = link.domain || window.location.host
|
||||
this.activeUrl = `https://${domain}/lnurlp//${link.id}`
|
||||
this.qrCodeDialog.show = true
|
||||
},
|
||||
openUpdateDialog(linkId) {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
<span v-text="col.label"></span>
|
||||
</q-th>
|
||||
<q-th auto-width></q-th>
|
||||
<q-th auto-width></q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props">
|
||||
|
|
@ -55,7 +54,6 @@
|
|||
><q-tooltip>Shareable Page</q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
unelevated
|
||||
dense
|
||||
size="xs"
|
||||
icon="visibility"
|
||||
|
|
@ -64,6 +62,27 @@
|
|||
@click="openQrCodeDialog(props.row.id)"
|
||||
><q-tooltip>View Link</q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
size="xs"
|
||||
@click="openUpdateDialog(props.row.id)"
|
||||
icon="edit"
|
||||
color="light-blue"
|
||||
class="q-ml-sm"
|
||||
>
|
||||
<q-tooltip>Edit</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
size="xs"
|
||||
@click="deletePayLink(props.row.id)"
|
||||
icon="cancel"
|
||||
color="pink"
|
||||
class="q-ml-sm"
|
||||
><q-tooltip>Delete</q-tooltip></q-btn
|
||||
>
|
||||
</q-td>
|
||||
<q-td
|
||||
v-for="col in props.cols"
|
||||
|
|
@ -104,27 +123,6 @@
|
|||
</q-tooltip>
|
||||
</q-icon>
|
||||
</q-td>
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
size="xs"
|
||||
@click="openUpdateDialog(props.row.id)"
|
||||
icon="edit"
|
||||
color="light-blue"
|
||||
>
|
||||
<q-tooltip>Edit</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
size="xs"
|
||||
@click="deletePayLink(props.row.id)"
|
||||
icon="cancel"
|
||||
color="pink"
|
||||
><q-tooltip>Delete</q-tooltip></q-btn
|
||||
>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
|
|
@ -402,10 +400,17 @@
|
|||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="col" style="margin-top: 10px">
|
||||
<span class="label">
|
||||
@ <span v-text="domain"></span>
|
||||
</span>
|
||||
<div class="col" style="flex: 0 0 auto; margin-top: 10px">
|
||||
<span class="label"> @ </span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.trim="formDialog.data.domain"
|
||||
type="text"
|
||||
:label="domain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-col-gutter-sm q-mx-sm">
|
||||
|
|
@ -642,7 +647,7 @@
|
|||
<span v-text="qrCodeDialog.data.success"></span><br />
|
||||
<span v-if="qrCodeDialog.data.username">
|
||||
<strong>Lightning Address: </strong>
|
||||
<span v-text="qrCodeDialog.data.username + '@' + domain"></span>
|
||||
<span v-text="lnaddress(qrCodeDialog.data)"></span>
|
||||
<br />
|
||||
</span>
|
||||
</p>
|
||||
|
|
|
|||
30
views_api.py
30
views_api.py
|
|
@ -23,15 +23,15 @@ from .crud import (
|
|||
update_lnurlp_settings,
|
||||
update_pay_link,
|
||||
)
|
||||
from .helpers import lnurl_encode_link_id, parse_nostr_private_key
|
||||
from .models import CreatePayLinkData, LnurlpSettings, PayLink
|
||||
from .helpers import lnurl_encode_link, parse_nostr_private_key
|
||||
from .models import CreatePayLinkData, LnurlpSettings, PayLink, PublicPayLink
|
||||
|
||||
lnurlp_api_router = APIRouter()
|
||||
|
||||
|
||||
def check_lnurl_encode(req: Request, link_id: str) -> str:
|
||||
def check_lnurl_encode(req: Request, link: PayLink) -> str:
|
||||
try:
|
||||
return lnurl_encode_link_id(req, link_id)
|
||||
return lnurl_encode_link(req, link.id, link.domain)
|
||||
except InvalidUrl as exc:
|
||||
raise HTTPException(
|
||||
detail=(
|
||||
|
|
@ -60,11 +60,11 @@ async def api_links(
|
|||
|
||||
links = await get_pay_links(wallet_ids)
|
||||
for link in links:
|
||||
link.lnurl = check_lnurl_encode(req=req, link_id=link.id)
|
||||
link.lnurl = check_lnurl_encode(req, link)
|
||||
return links
|
||||
|
||||
|
||||
@lnurlp_api_router.get("/api/v1/links/{link_id}", status_code=HTTPStatus.OK)
|
||||
@lnurlp_api_router.get("/api/v1/links/{link_id}")
|
||||
async def api_link_retrieve(
|
||||
req: Request, link_id: str, key_info: WalletTypeInfo = Depends(require_invoice_key)
|
||||
) -> PayLink:
|
||||
|
|
@ -85,7 +85,18 @@ async def api_link_retrieve(
|
|||
detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN
|
||||
)
|
||||
|
||||
link.lnurl = check_lnurl_encode(req, link.id)
|
||||
link.lnurl = check_lnurl_encode(req, link)
|
||||
return link
|
||||
|
||||
|
||||
@lnurlp_api_router.get("/api/v1/links/public/{link_id}", response_model=PublicPayLink)
|
||||
async def api_link_public_retrieve(req: Request, link_id: str) -> PayLink:
|
||||
link = await get_pay_link(link_id)
|
||||
if not link:
|
||||
raise HTTPException(
|
||||
detail="Pay link does not exist.", status_code=HTTPStatus.NOT_FOUND
|
||||
)
|
||||
link.lnurl = lnurl_encode_link(req, link.id, link.domain)
|
||||
return link
|
||||
|
||||
|
||||
|
|
@ -168,7 +179,7 @@ async def api_link_create_or_update(
|
|||
detail="Wallet does not exist.", status_code=HTTPStatus.FORBIDDEN
|
||||
)
|
||||
|
||||
# admins are allowed to create/edit paylinks beloging to regular users
|
||||
# admins are allowed to create/edit paylinks belonging to regular users
|
||||
user = await get_user(key_info.wallet.user)
|
||||
admin_user = user.admin if user else False
|
||||
if not admin_user and new_wallet.user != key_info.wallet.user:
|
||||
|
|
@ -197,8 +208,7 @@ async def api_link_create_or_update(
|
|||
|
||||
link = await create_pay_link(data)
|
||||
|
||||
link.lnurl = check_lnurl_encode(req=req, link_id=link.id)
|
||||
|
||||
link.lnurl = check_lnurl_encode(req, link)
|
||||
return link
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ async def api_lnurl_callback(
|
|||
extra["nostr"] = nostr # put it here for later publishing in tasks.py
|
||||
|
||||
if link.username:
|
||||
identifier = f"{link.username}@{request.url.netloc}"
|
||||
identifier = f"{link.username}@{link.domain or request.url.netloc}"
|
||||
text = f"Payment to {link.username}"
|
||||
_metadata = [["text/plain", text], ["text/identifier", identifier]]
|
||||
extra["lnaddress"] = identifier
|
||||
|
|
@ -173,7 +173,7 @@ async def api_lnurl_response(
|
|||
callback_url = parse_obj_as(CallbackUrl, str(url))
|
||||
|
||||
if link.username:
|
||||
identifier = f"{link.username}@{request.url.netloc}"
|
||||
identifier = f"{link.username}@{link.domain or request.url.netloc}"
|
||||
text = f"Payment to {link.username}"
|
||||
metadata = [["text/plain", text], ["text/identifier", identifier]]
|
||||
else:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue