configuration for nostr
This commit is contained in:
parent
db607e463e
commit
64da75d605
7 changed files with 170 additions and 95 deletions
6
crud.py
6
crud.py
|
|
@ -58,10 +58,11 @@ async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink:
|
||||||
comment_chars,
|
comment_chars,
|
||||||
currency,
|
currency,
|
||||||
fiat_base_multiplier,
|
fiat_base_multiplier,
|
||||||
username
|
username,
|
||||||
|
zaps
|
||||||
|
|
||||||
)
|
)
|
||||||
VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
link_id,
|
link_id,
|
||||||
|
|
@ -78,6 +79,7 @@ async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink:
|
||||||
data.currency,
|
data.currency,
|
||||||
data.fiat_base_multiplier,
|
data.fiat_base_multiplier,
|
||||||
data.username,
|
data.username,
|
||||||
|
data.zaps,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
assert result
|
assert result
|
||||||
|
|
|
||||||
1
lnurl.py
1
lnurl.py
|
|
@ -147,6 +147,7 @@ async def api_lnurl_response(request: Request, link_id, lnaddress=False):
|
||||||
if link.comment_chars > 0:
|
if link.comment_chars > 0:
|
||||||
params["commentAllowed"] = link.comment_chars
|
params["commentAllowed"] = link.comment_chars
|
||||||
|
|
||||||
|
if link.zaps:
|
||||||
params["allowsNostr"] = True
|
params["allowsNostr"] = True
|
||||||
params["nostrPubkey"] = nostr_publickey.hex()
|
params["nostrPubkey"] = nostr_publickey.hex()
|
||||||
return params
|
return params
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,13 @@ async def m006_redux(db):
|
||||||
|
|
||||||
async def m007_add_lnaddress_username(db):
|
async def m007_add_lnaddress_username(db):
|
||||||
"""
|
"""
|
||||||
Add headers and body to webhooks
|
Add Lightning address to pay links
|
||||||
"""
|
"""
|
||||||
await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN username TEXT;")
|
await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN username TEXT;")
|
||||||
|
|
||||||
|
|
||||||
|
async def m008_add_zap_enabled_column(db):
|
||||||
|
"""
|
||||||
|
Add Nostr zaps to pay links
|
||||||
|
"""
|
||||||
|
await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN zaps BOOLEAN;")
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ class CreatePayLinkData(BaseModel):
|
||||||
success_url: str = Query(None)
|
success_url: str = Query(None)
|
||||||
fiat_base_multiplier: int = Query(100, ge=1)
|
fiat_base_multiplier: int = Query(100, ge=1)
|
||||||
username: str = Query(None)
|
username: str = Query(None)
|
||||||
|
zaps: bool = Query(False)
|
||||||
|
|
||||||
|
|
||||||
class PayLink(BaseModel):
|
class PayLink(BaseModel):
|
||||||
|
|
@ -34,6 +35,7 @@ class PayLink(BaseModel):
|
||||||
served_meta: int
|
served_meta: int
|
||||||
served_pr: int
|
served_pr: int
|
||||||
username: Optional[str]
|
username: Optional[str]
|
||||||
|
zaps: Optional[bool]
|
||||||
domain: Optional[str]
|
domain: Optional[str]
|
||||||
webhook_url: Optional[str]
|
webhook_url: Optional[str]
|
||||||
webhook_headers: Optional[str]
|
webhook_headers: Optional[str]
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,9 @@ new Vue({
|
||||||
formDialog: {
|
formDialog: {
|
||||||
show: false,
|
show: false,
|
||||||
fixedAmount: true,
|
fixedAmount: true,
|
||||||
data: {}
|
data: {
|
||||||
|
zaps:false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
qrCodeDialog: {
|
qrCodeDialog: {
|
||||||
show: false,
|
show: false,
|
||||||
|
|
@ -140,7 +142,8 @@ new Vue({
|
||||||
'success_url',
|
'success_url',
|
||||||
'comment_chars',
|
'comment_chars',
|
||||||
'currency',
|
'currency',
|
||||||
'username'
|
'username',
|
||||||
|
'zaps'
|
||||||
),
|
),
|
||||||
(value, key) =>
|
(value, key) =>
|
||||||
(key === 'webhook_url' ||
|
(key === 'webhook_url' ||
|
||||||
|
|
|
||||||
7
tasks.py
7
tasks.py
|
|
@ -72,9 +72,9 @@ async def on_invoice_paid(payment: Payment):
|
||||||
)
|
)
|
||||||
|
|
||||||
# NIP-57
|
# NIP-57
|
||||||
|
# load the zap request
|
||||||
nostr = payment.extra.get("nostr")
|
nostr = payment.extra.get("nostr")
|
||||||
if nostr:
|
if pay_link and pay_link.zaps and nostr:
|
||||||
|
|
||||||
event_json = json.loads(nostr)
|
event_json = json.loads(nostr)
|
||||||
|
|
||||||
def get_tag(event_json, tag):
|
def get_tag(event_json, tag):
|
||||||
|
|
@ -114,7 +114,7 @@ async def on_invoice_paid(payment: Payment):
|
||||||
wsts: List[Thread] = []
|
wsts: List[Thread] = []
|
||||||
|
|
||||||
# # send zap via nostrclient
|
# # send zap via nostrclient
|
||||||
# ws, wst = send_zap(f"ws://localhost:{settings.port}/nostrclient/api/v1/relay")
|
# ws, wst = send_zap(f"wss://localhost:{settings.port}/nostrclient/api/v1/relay")
|
||||||
# wss += [ws]
|
# wss += [ws]
|
||||||
# wsts += [wst]
|
# wsts += [wst]
|
||||||
|
|
||||||
|
|
@ -138,7 +138,6 @@ async def on_invoice_paid(payment: Payment):
|
||||||
async def mark_webhook_sent(
|
async def mark_webhook_sent(
|
||||||
payment_hash: str, status: int, is_success: bool, reason_phrase="", text=""
|
payment_hash: str, status: int, is_success: bool, reason_phrase="", text=""
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
await update_payment_extra(
|
await update_payment_extra(
|
||||||
payment_hash,
|
payment_hash,
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,8 @@
|
||||||
type="a"
|
type="a"
|
||||||
:href="props.row.pay_url"
|
:href="props.row.pay_url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
><q-tooltip>Sharable Page</q-tooltip></q-btn>
|
><q-tooltip>Sharable Page</q-tooltip></q-btn
|
||||||
|
>
|
||||||
<q-btn
|
<q-btn
|
||||||
unelevated
|
unelevated
|
||||||
dense
|
dense
|
||||||
|
|
@ -56,7 +57,8 @@
|
||||||
icon="visibility"
|
icon="visibility"
|
||||||
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||||
@click="openQrCodeDialog(props.row.id)"
|
@click="openQrCodeDialog(props.row.id)"
|
||||||
><q-tooltip>View Link</q-tooltip></q-btn>
|
><q-tooltip>View Link</q-tooltip></q-btn
|
||||||
|
>
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td auto-width>{{ props.row.description }}</q-td>
|
<q-td auto-width>{{ props.row.description }}</q-td>
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
|
|
@ -66,7 +68,11 @@
|
||||||
<span v-else>{{ props.row.min }} - {{ props.row.max }}</span>
|
<span v-else>{{ props.row.min }} - {{ props.row.max }}</span>
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td>{{ props.row.currency || 'sat' }}</q-td>
|
<q-td>{{ props.row.currency || 'sat' }}</q-td>
|
||||||
<q-td auto-width :class="(props.row.username) ? 'text-normal' : 'text-grey'">{{ props.row.username || 'None' }}</q-td>
|
<q-td
|
||||||
|
auto-width
|
||||||
|
:class="(props.row.username) ? 'text-normal' : 'text-grey'"
|
||||||
|
>{{ props.row.username || 'None' }}</q-td
|
||||||
|
>
|
||||||
<q-td>
|
<q-td>
|
||||||
<q-icon v-if="props.row.webhook_url" size="14px" name="http">
|
<q-icon v-if="props.row.webhook_url" size="14px" name="http">
|
||||||
<q-tooltip>Webhook to {{ props.row.webhook_url }}</q-tooltip>
|
<q-tooltip>Webhook to {{ props.row.webhook_url }}</q-tooltip>
|
||||||
|
|
@ -111,7 +117,8 @@
|
||||||
@click="deletePayLink(props.row.id)"
|
@click="deletePayLink(props.row.id)"
|
||||||
icon="cancel"
|
icon="cancel"
|
||||||
color="pink"
|
color="pink"
|
||||||
><q-tooltip>Delete</q-tooltip></q-btn>
|
><q-tooltip>Delete</q-tooltip></q-btn
|
||||||
|
>
|
||||||
</q-td>
|
</q-td>
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -167,14 +174,15 @@
|
||||||
v-model.trim="formDialog.data.username"
|
v-model.trim="formDialog.data.username"
|
||||||
type="text"
|
type="text"
|
||||||
label="Lightning Address"
|
label="Lightning Address"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col" style="margin-top: 10px">
|
<div class="col" style="margin-top: 10px">
|
||||||
<span class="label"> @ {% raw %} {{domain}} {% endraw %} </span>
|
<span class="label">
|
||||||
|
@ {% raw %} {{ domain }} {% endraw %}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</q-input>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row q-col-gutter-sm">
|
<div class="row q-col-gutter-sm q-mx-sm">
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
|
|
@ -209,20 +217,34 @@
|
||||||
v-model="formDialog.data.currency"
|
v-model="formDialog.data.currency"
|
||||||
:display-value="formDialog.data.currency || 'satoshis'"
|
:display-value="formDialog.data.currency || 'satoshis'"
|
||||||
label="Currency"
|
label="Currency"
|
||||||
:hint="'Amounts will be converted at use-time to satoshis. ' + (formDialog.data.currency && fiatRates[formDialog.data.currency] ? `Currently 1 ${formDialog.data.currency} = ${fiatRates[formDialog.data.currency]} sat` : '')"
|
:hint="'Converted to satoshis at each payment. ' + (formDialog.data.currency && fiatRates[formDialog.data.currency] ? `Currently 1 ${formDialog.data.currency} = ${fiatRates[formDialog.data.currency]} sat` : '')"
|
||||||
@input="updateFiatRate"
|
@input="updateFiatRate"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<q-expansion-item
|
||||||
|
group="advanced"
|
||||||
|
icon="settings"
|
||||||
|
label="Advanced options"
|
||||||
|
>
|
||||||
|
<q-card>
|
||||||
|
<q-card-section>
|
||||||
|
<h5 class="text-caption q-mt-sm q-mb-none">LNURL</h5>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
v-model.number="formDialog.data.comment_chars"
|
v-model.number="formDialog.data.comment_chars"
|
||||||
type="number"
|
type="number"
|
||||||
label="Comment maximum characters"
|
label="Comment maximum characters"
|
||||||
hint="Tell wallets to prompt users for a comment that will be sent along with the payment. LNURLp will store the comment and send it in the webhook."
|
hint="Allow the payer to attach a comment."
|
||||||
>
|
>
|
||||||
</q-input>
|
</q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
|
|
@ -231,6 +253,10 @@
|
||||||
label="Webhook URL (optional)"
|
label="Webhook URL (optional)"
|
||||||
hint="A URL to be called whenever this link receives a payment."
|
hint="A URL to be called whenever this link receives a payment."
|
||||||
></q-input>
|
></q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
|
|
@ -240,6 +266,10 @@
|
||||||
label="Webhook headers (optional)"
|
label="Webhook headers (optional)"
|
||||||
hint="Custom data as JSON string, send headers along with the webhook."
|
hint="Custom data as JSON string, send headers along with the webhook."
|
||||||
></q-input>
|
></q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
|
|
@ -249,6 +279,10 @@
|
||||||
label="Webhook custom data (optional)"
|
label="Webhook custom data (optional)"
|
||||||
hint="Custom data as JSON string, will get posted along with webhook 'body' field."
|
hint="Custom data as JSON string, will get posted along with webhook 'body' field."
|
||||||
></q-input>
|
></q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
|
|
@ -257,15 +291,37 @@
|
||||||
label="Success message (optional)"
|
label="Success message (optional)"
|
||||||
hint="Will be shown to the user in his wallet after a successful payment."
|
hint="Will be shown to the user in his wallet after a successful payment."
|
||||||
></q-input>
|
></q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
v-model="formDialog.data.success_url"
|
v-model="formDialog.data.success_url"
|
||||||
type="text"
|
type="text"
|
||||||
label="Success URL (optional)"
|
label="Success URL (optional)"
|
||||||
hint="Will be shown as a clickable link to the user in his wallet after a successful payment, appended by the payment_hash as a query string."
|
hint="Link will be shown to the sender after a successful payment."
|
||||||
>
|
>
|
||||||
</q-input>
|
</q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-section>
|
||||||
|
<h5 class="text-caption q-mt-sm q-mb-none">Nostr</h5>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<q-checkbox
|
||||||
|
:toggle-indeterminate="false"
|
||||||
|
dense
|
||||||
|
v-model="formDialog.data.zaps"
|
||||||
|
label="Enable nostr zaps"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
</q-expansion-item>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn
|
<q-btn
|
||||||
v-if="formDialog.data.id"
|
v-if="formDialog.data.id"
|
||||||
|
|
@ -311,16 +367,21 @@
|
||||||
<strong>ID:</strong> {{ qrCodeDialog.data.id }}<br />
|
<strong>ID:</strong> {{ qrCodeDialog.data.id }}<br />
|
||||||
<strong>Amount:</strong> {{ qrCodeDialog.data.amount }}<br />
|
<strong>Amount:</strong> {{ qrCodeDialog.data.amount }}<br />
|
||||||
<span v-if="qrCodeDialog.data.currency"
|
<span v-if="qrCodeDialog.data.currency"
|
||||||
><strong>{{ qrCodeDialog.data.currency }} price:</strong> {{
|
><strong>{{ qrCodeDialog.data.currency }} price:</strong>
|
||||||
fiatRates[qrCodeDialog.data.currency] ?
|
{{
|
||||||
fiatRates[qrCodeDialog.data.currency] + ' sat' : 'Loading...' }}<br
|
fiatRates[qrCodeDialog.data.currency]
|
||||||
|
? fiatRates[qrCodeDialog.data.currency] + ' sat'
|
||||||
|
: 'Loading...'
|
||||||
|
}}<br
|
||||||
/></span>
|
/></span>
|
||||||
<strong>Accepts comments:</strong> {{ qrCodeDialog.data.comments }}<br />
|
<strong>Accepts comments:</strong> {{ qrCodeDialog.data.comments
|
||||||
|
}}<br />
|
||||||
<strong>Dispatches webhook to:</strong> {{ qrCodeDialog.data.webhook
|
<strong>Dispatches webhook to:</strong> {{ qrCodeDialog.data.webhook
|
||||||
}}<br />
|
}}<br />
|
||||||
<strong>On success:</strong> {{ qrCodeDialog.data.success }}<br />
|
<strong>On success:</strong> {{ qrCodeDialog.data.success }}<br />
|
||||||
<span v-if="qrCodeDialog.data.username">
|
<span v-if="qrCodeDialog.data.username">
|
||||||
<strong>Lightning Address: </strong> {{ qrCodeDialog.data.username}}@{{domain}}
|
<strong>Lightning Address: </strong>
|
||||||
|
{{ qrCodeDialog.data.username }}@{{ domain }}
|
||||||
<br />
|
<br />
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue