798 lines
24 KiB
HTML
798 lines
24 KiB
HTML
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
|
%} {% block page %}
|
|
<div class="row q-col-gutter-md">
|
|
<div class="col-12 col-md-7 q-gutter-y-md">
|
|
<q-card>
|
|
<q-card-section>
|
|
{% raw %}
|
|
<q-btn unelevated color="primary" @click="formDialogCharge.show = true"
|
|
>New charge
|
|
</q-btn>
|
|
|
|
<q-btn
|
|
unelevated
|
|
color="primary"
|
|
@click="getSettings();formDialogSettings.show = true"
|
|
>SatsPay settings
|
|
</q-btn>
|
|
</q-card-section>
|
|
</q-card>
|
|
|
|
<q-card>
|
|
<q-card-section>
|
|
<div class="row items-center no-wrap q-mb-md">
|
|
<div class="col">
|
|
<h5 class="text-subtitle1 q-my-none">Charges</h5>
|
|
</div>
|
|
|
|
<div class="col q-pr-lg">
|
|
<q-input
|
|
borderless
|
|
dense
|
|
debounce="300"
|
|
v-model="filter"
|
|
placeholder="Search"
|
|
class="float-right"
|
|
>
|
|
<template v-slot:append>
|
|
<q-icon name="search"></q-icon>
|
|
</template>
|
|
</q-input>
|
|
</div>
|
|
<div class="col-auto">
|
|
<q-btn outline color="grey" label="...">
|
|
<q-menu auto-close>
|
|
<q-list style="min-width: 100px">
|
|
<q-item clickable>
|
|
<q-item-section @click="exportchargeCSV"
|
|
>Export to CSV</q-item-section
|
|
>
|
|
</q-item>
|
|
</q-list>
|
|
</q-menu>
|
|
</q-btn>
|
|
</div>
|
|
</div>
|
|
<q-table
|
|
flat
|
|
dense
|
|
:data="chargeLinks"
|
|
row-key="id"
|
|
:columns="chargesTable.columns"
|
|
:pagination.sync="chargesTable.pagination"
|
|
:filter="filter"
|
|
>
|
|
<template v-slot:header="props">
|
|
<q-tr :props="props">
|
|
<q-th auto-width></q-th>
|
|
<q-th auto-width>Status </q-th>
|
|
<q-th auto-width>Title</q-th>
|
|
<q-th auto-width>Time Left (hh:mm)</q-th>
|
|
<q-th auto-width>Time To Pay (hh:mm)</q-th>
|
|
<q-th auto-width>Amount To Pay</q-th>
|
|
<q-th auto-width>Balance</q-th>
|
|
<q-th auto-width>Pending Balance</q-th>
|
|
<q-th auto-width>Onchain Address</q-th>
|
|
<q-th auto-width></q-th>
|
|
</q-tr>
|
|
</template>
|
|
|
|
<template v-slot:body="props">
|
|
<q-tr :props="props">
|
|
<q-td auto-width>
|
|
<q-btn
|
|
size="sm"
|
|
color="accent"
|
|
round
|
|
dense
|
|
@click="props.row.expanded= !props.row.expanded"
|
|
:icon="props.row.expanded? 'remove' : 'add'"
|
|
/>
|
|
</q-td>
|
|
|
|
<q-td auto-width>
|
|
<q-badge
|
|
v-if="props.row.time_elapsed && props.row.balance < props.row.amount"
|
|
color="red"
|
|
>
|
|
<a
|
|
:href="props.row.displayUrl"
|
|
target="_blank"
|
|
style="color: unset; text-decoration: none"
|
|
>expired</a
|
|
>
|
|
</q-badge>
|
|
|
|
<q-badge
|
|
v-else-if="props.row.balance >= props.row.amount"
|
|
color="green"
|
|
>
|
|
<a
|
|
:href="props.row.displayUrl"
|
|
target="_blank"
|
|
style="color: unset; text-decoration: none"
|
|
>paid</a
|
|
>
|
|
</q-badge>
|
|
|
|
<q-badge v-else color="blue"
|
|
><a
|
|
:href="props.row.displayUrl"
|
|
target="_blank"
|
|
style="color: unset; text-decoration: none"
|
|
>waiting</a
|
|
>
|
|
</q-badge>
|
|
</q-td>
|
|
<q-td key="description" :props="props" :class="">
|
|
<a
|
|
:href="props.row.displayUrl"
|
|
target="_blank"
|
|
style="color: unset; text-decoration: none"
|
|
>{{props.row.description}}</a
|
|
>
|
|
</q-td>
|
|
<q-td key="timeLeft" :props="props" :class="">
|
|
<div>{{props.row.timeLeft}}</div>
|
|
<q-linear-progress
|
|
v-if="props.row.timeLeft"
|
|
:value="props.row.progress"
|
|
color="secondary"
|
|
>
|
|
</q-linear-progress>
|
|
</q-td>
|
|
<q-td key="time to pay" :props="props" :class="">
|
|
<div>{{props.row.time}}</div>
|
|
</q-td>
|
|
<q-td key="amount" :props="props" :class="">
|
|
<div>{{props.row.amount}}</div>
|
|
</q-td>
|
|
<q-td key="balance" :props="props" :class="">
|
|
<div>{{props.row.balance}}</div>
|
|
</q-td>
|
|
<q-td key="pendingBalance" :props="props" :class="">
|
|
<div>
|
|
{{props.row.pendingBalance ? props.row.pendingBalance : ''}}
|
|
</div>
|
|
</q-td>
|
|
<q-td key="onchain address" :props="props" :class="">
|
|
<a
|
|
:href="props.row.displayUrl"
|
|
target="_blank"
|
|
style="color: unset; text-decoration: none"
|
|
>{{props.row.onchainaddress}}</a
|
|
>
|
|
</q-td>
|
|
</q-tr>
|
|
<q-tr v-show="props.row.expanded" :props="props">
|
|
<q-td colspan="100%">
|
|
<div
|
|
v-if="props.row.onchainwallet"
|
|
class="row items-center q-mt-md q-mb-lg"
|
|
>
|
|
<div class="col-2 q-pr-lg">Onchain Wallet:</div>
|
|
<div class="col-4 q-pr-lg">
|
|
{{getOnchainWalletName(props.row.onchainwallet)}}
|
|
</div>
|
|
</div>
|
|
<div
|
|
v-if="props.row.lnbitswallet"
|
|
class="row items-center q-mt-md q-mb-lg"
|
|
>
|
|
<div class="col-2 q-pr-lg">LNbits Wallet:</div>
|
|
<div class="col-4 q-pr-lg">
|
|
{{getLNbitsWalletName(props.row.lnbitswallet)}}
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
v-if="props.row.completelink || props.row.completelinktext"
|
|
class="row items-center q-mt-md q-mb-lg"
|
|
>
|
|
<div class="col-2 q-pr-lg">Completed Link:</div>
|
|
<div class="col-4 q-pr-lg">
|
|
<a
|
|
:href="props.row.completelink"
|
|
target="_blank"
|
|
style="color: unset; text-decoration: none"
|
|
>{{props.row.completelinktext ||
|
|
props.row.completelink}}</a
|
|
>
|
|
</div>
|
|
</div>
|
|
<div
|
|
v-if="props.row.webhook"
|
|
class="row items-center q-mt-md q-mb-lg"
|
|
>
|
|
<div class="col-2 q-pr-lg">Webhook:</div>
|
|
<div class="col-4 q-pr-lg">
|
|
<a
|
|
:href="props.row.webhook"
|
|
target="_blank"
|
|
style="color: unset; text-decoration: none"
|
|
>{{props.row.webhook}}</a
|
|
>
|
|
</div>
|
|
<div class="col-4 q-pr-lg">
|
|
<q-badge v-if="props.row.webhook_message" color="blue">
|
|
{{props.row.webhook_message }}
|
|
</q-badge>
|
|
</div>
|
|
</div>
|
|
<div class="row items-center q-mt-md q-mb-lg">
|
|
<div class="col-2 q-pr-lg">ID:</div>
|
|
<div class="col-4 q-pr-lg">{{props.row.id}}</div>
|
|
</div>
|
|
<div class="row items-center q-mt-md q-mb-lg">
|
|
<div class="col-2 q-pr-lg"></div>
|
|
<div class="col-6 q-pr-lg">
|
|
<q-btn
|
|
unelevated
|
|
color="gray"
|
|
outline
|
|
type="a"
|
|
:href="props.row.displayUrl"
|
|
target="_blank"
|
|
class="float-left q-mr-lg"
|
|
>Details</q-btn
|
|
>
|
|
<q-btn
|
|
unelevated
|
|
color="gray"
|
|
outline
|
|
type="a"
|
|
@click="refreshBalance(props.row)"
|
|
target="_blank"
|
|
class="float-left"
|
|
>Refresh Balance</q-btn
|
|
>
|
|
</div>
|
|
<div class="col-4 q-pr-lg">
|
|
<q-btn
|
|
unelevated
|
|
color="pink"
|
|
icon="cancel"
|
|
@click="deleteChargeLink(props.row.id)"
|
|
>Delete</q-btn
|
|
>
|
|
</div>
|
|
<div class="col-4"></div>
|
|
<div class="col-2 q-pr-lg"></div>
|
|
</div>
|
|
</q-td>
|
|
</q-tr>
|
|
</template>
|
|
{% endraw %}
|
|
</q-table>
|
|
</q-card-section>
|
|
</q-card>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-5 q-gutter-y-md">
|
|
<q-card>
|
|
<q-card-section>
|
|
<h6 class="text-subtitle1 q-my-none">
|
|
{{SITE_TITLE}} satspay Extension
|
|
</h6>
|
|
</q-card-section>
|
|
<q-card-section class="q-pa-none">
|
|
<q-separator></q-separator>
|
|
<q-list> {% include "satspay/_api_docs.html" %} </q-list>
|
|
</q-card-section>
|
|
</q-card>
|
|
</div>
|
|
<q-dialog v-model="formDialogCharge.show" position="top">
|
|
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
|
<q-form @submit="sendFormDataCharge" class="q-gutter-md">
|
|
<q-input
|
|
filled
|
|
dense
|
|
v-model.trim="formDialogCharge.data.description"
|
|
type="text"
|
|
label="*Description"
|
|
></q-input>
|
|
|
|
<q-input
|
|
filled
|
|
dense
|
|
v-model.trim="formDialogCharge.data.amount"
|
|
type="number"
|
|
label="*Amount (sats)"
|
|
></q-input>
|
|
|
|
<q-input
|
|
filled
|
|
dense
|
|
v-model.trim="formDialogCharge.data.time"
|
|
type="number"
|
|
max="1440"
|
|
label="*Mins valid for (max 1440)"
|
|
>
|
|
</q-input>
|
|
|
|
<q-input
|
|
filled
|
|
dense
|
|
v-model.trim="formDialogCharge.data.webhook"
|
|
type="url"
|
|
label="Webhook (URL to send transaction data to once paid)"
|
|
>
|
|
</q-input>
|
|
|
|
<q-input
|
|
filled
|
|
dense
|
|
v-model.trim="formDialogCharge.data.completelink"
|
|
type="url"
|
|
label="Completed button URL"
|
|
>
|
|
</q-input>
|
|
<q-input
|
|
filled
|
|
dense
|
|
v-model.trim="formDialogCharge.data.completelinktext"
|
|
type="text"
|
|
label="Completed button text (ie 'Back to merchant')"
|
|
>
|
|
</q-input>
|
|
|
|
<div class="row">
|
|
<div class="col">
|
|
<div v-if="walletLinks.length > 0">
|
|
<q-checkbox
|
|
v-model="formDialogCharge.data.onchain"
|
|
label="Onchain"
|
|
/>
|
|
</div>
|
|
<div v-else>
|
|
<q-checkbox :value="false" label="Onchain" disabled>
|
|
<q-tooltip>
|
|
Onchain Wallet (watch-only) extension MUST be activated and
|
|
have a wallet
|
|
</q-tooltip>
|
|
</q-checkbox>
|
|
</div>
|
|
</div>
|
|
<div class="col">
|
|
<div>
|
|
<q-checkbox
|
|
v-model="formDialogCharge.data.lnbits"
|
|
label="LNbits wallet"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="formDialogCharge.data.onchain">
|
|
<q-select
|
|
filled
|
|
dense
|
|
emit-value
|
|
v-model="onchainwallet"
|
|
:options="walletLinks"
|
|
label="Onchain Wallet"
|
|
/>
|
|
</div>
|
|
|
|
<q-select
|
|
v-if="formDialogCharge.data.lnbits"
|
|
filled
|
|
dense
|
|
emit-value
|
|
v-model="formDialogCharge.data.lnbitswallet"
|
|
:options="g.user.walletOptions"
|
|
label="Wallet *"
|
|
>
|
|
</q-select>
|
|
<div class="row q-mt-lg">
|
|
<q-btn
|
|
unelevated
|
|
color="primary"
|
|
:disable="
|
|
formDialogCharge.data.time == null ||
|
|
formDialogCharge.data.amount == null"
|
|
type="submit"
|
|
>Create Charge</q-btn
|
|
>
|
|
<q-btn @click="cancelCharge" flat color="grey" class="q-ml-auto"
|
|
>Cancel</q-btn
|
|
>
|
|
</div>
|
|
</q-form>
|
|
</q-card>
|
|
</q-dialog>
|
|
|
|
<q-dialog v-model="formDialogSettings.show" position="top">
|
|
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
|
<q-form @submit="sendFormDataSettings" class="q-gutter-md">
|
|
<q-input
|
|
filled
|
|
dense
|
|
v-model.trim="formDialogSettings.data.custom_css"
|
|
type="textarea"
|
|
label="Custom CSS"
|
|
>
|
|
<q-tooltip
|
|
>Custom CSS to apply styles to your SatsPay invoice</q-tooltip
|
|
>
|
|
</q-input>
|
|
<div class="row q-mt-lg">
|
|
<q-btn unelevated color="primary" type="submit">Save Settings</q-btn>
|
|
<q-btn @click="cancelSettings" flat color="grey" class="q-ml-auto"
|
|
>Cancel</q-btn
|
|
>
|
|
</div>
|
|
</q-form>
|
|
</q-card>
|
|
</q-dialog>
|
|
</div>
|
|
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
|
<!-- lnbits/static/vendor
|
|
<script src="/vendor/vue-qrcode@1.0.2/vue-qrcode.min.js"></script> -->
|
|
<style></style>
|
|
<!-- todo: use config mempool -->
|
|
<script src="https://mempool.space/mempool.js"></script>
|
|
<script src="{{ url_for('satspay_static', path='js/utils.js') }}"></script>
|
|
<script>
|
|
Vue.component(VueQrcode.name, VueQrcode)
|
|
|
|
new Vue({
|
|
el: '#vue',
|
|
mixins: [windowMixin],
|
|
data: function () {
|
|
return {
|
|
settings: {},
|
|
filter: '',
|
|
balance: null,
|
|
walletLinks: [],
|
|
chargeLinks: [],
|
|
onchainwallet: null,
|
|
rescanning: false,
|
|
mempool: {
|
|
endpoint: '',
|
|
network: 'Mainnet'
|
|
},
|
|
|
|
chargesTable: {
|
|
columns: [
|
|
{
|
|
name: 'theId',
|
|
align: 'left',
|
|
label: 'ID',
|
|
field: 'id'
|
|
},
|
|
{
|
|
name: 'description',
|
|
align: 'left',
|
|
label: 'Title',
|
|
field: 'description'
|
|
},
|
|
{
|
|
name: 'timeLeft',
|
|
align: 'left',
|
|
label: 'Time left',
|
|
field: 'timeLeft'
|
|
},
|
|
{
|
|
name: 'time to pay',
|
|
align: 'left',
|
|
label: 'Time to Pay',
|
|
field: 'time'
|
|
},
|
|
{
|
|
name: 'amount',
|
|
align: 'left',
|
|
label: 'Amount to pay',
|
|
field: 'amount'
|
|
},
|
|
{
|
|
name: 'balance',
|
|
align: 'left',
|
|
label: 'Balance',
|
|
field: 'balance'
|
|
},
|
|
{
|
|
name: 'pendingBalance',
|
|
align: 'left',
|
|
label: 'Pending Balance',
|
|
field: 'pendingBalance'
|
|
},
|
|
{
|
|
name: 'onchain address',
|
|
align: 'left',
|
|
label: 'Onchain Address',
|
|
field: 'onchainaddress'
|
|
},
|
|
{
|
|
name: 'LNbits wallet',
|
|
align: 'left',
|
|
label: 'LNbits wallet',
|
|
field: 'lnbitswallet'
|
|
},
|
|
{
|
|
name: 'Webhook link',
|
|
align: 'left',
|
|
label: 'Webhook link',
|
|
field: 'webhook'
|
|
},
|
|
{
|
|
name: 'Paid link',
|
|
align: 'left',
|
|
label: 'Paid link',
|
|
field: 'completelink'
|
|
}
|
|
],
|
|
pagination: {
|
|
rowsPerPage: 10
|
|
}
|
|
},
|
|
|
|
formDialogCharge: {
|
|
show: false,
|
|
data: {
|
|
onchain: false,
|
|
onchainwallet: '',
|
|
lnbits: false,
|
|
description: '',
|
|
time: null,
|
|
amount: null
|
|
}
|
|
},
|
|
formDialogSettings: {
|
|
show: false,
|
|
data: {
|
|
custom_css: ''
|
|
}
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
cancelSettings: function (data) {
|
|
this.formDialogCharge.data.custom_css = ''
|
|
this.formDialogSettings.show = false
|
|
},
|
|
cancelCharge: function (data) {
|
|
this.formDialogCharge.data.description = ''
|
|
this.formDialogCharge.data.onchain = false
|
|
this.formDialogCharge.data.onchainwallet = ''
|
|
this.formDialogCharge.data.lnbitswallet = ''
|
|
this.formDialogCharge.data.time = null
|
|
this.formDialogCharge.data.amount = null
|
|
this.formDialogCharge.data.webhook = ''
|
|
this.formDialogCharge.data.completelink = ''
|
|
this.formDialogCharge.show = false
|
|
},
|
|
|
|
getWalletLinks: async function () {
|
|
try {
|
|
const {data} = await LNbits.api.request(
|
|
'GET',
|
|
`/watchonly/api/v1/wallet?network=${this.mempool.network}`,
|
|
this.g.user.wallets[0].inkey
|
|
)
|
|
this.walletLinks = data.map(w => ({
|
|
id: w.id,
|
|
label: w.title + ' - ' + w.id
|
|
}))
|
|
} catch (error) {
|
|
LNbits.utils.notifyApiError(error)
|
|
}
|
|
},
|
|
|
|
getWalletConfig: async function () {
|
|
try {
|
|
const {data} = await LNbits.api.request(
|
|
'GET',
|
|
'/watchonly/api/v1/config',
|
|
this.g.user.wallets[0].inkey
|
|
)
|
|
this.mempool.endpoint = data.mempool_endpoint
|
|
this.mempool.network = data.network || 'Mainnet'
|
|
const url = new URL(this.mempool.endpoint)
|
|
this.mempool.hostname = url.hostname
|
|
} catch (error) {
|
|
LNbits.utils.notifyApiError(error)
|
|
}
|
|
},
|
|
getOnchainWalletName: function (walletId) {
|
|
const wallet = this.walletLinks.find(w => w.id === walletId)
|
|
if (!wallet) return 'unknown'
|
|
return wallet.label
|
|
},
|
|
getLNbitsWalletName: function (walletId) {
|
|
const wallet = this.g.user.walletOptions.find(w => w.value === walletId)
|
|
if (!wallet) return 'unknown'
|
|
return wallet.label
|
|
},
|
|
|
|
getCharges: async function () {
|
|
try {
|
|
const {data} = await LNbits.api.request(
|
|
'GET',
|
|
'/satspay/api/v1/charges',
|
|
this.g.user.wallets[0].inkey
|
|
)
|
|
this.chargeLinks = data.map(c =>
|
|
mapCharge(
|
|
c,
|
|
this.chargeLinks.find(old => old.id === c.id)
|
|
)
|
|
)
|
|
} catch (error) {
|
|
LNbits.utils.notifyApiError(error)
|
|
}
|
|
},
|
|
|
|
getSettings: async function () {
|
|
try {
|
|
const {data} = await LNbits.api.request(
|
|
'GET',
|
|
'/satspay/api/v1/settings',
|
|
this.g.user.wallets[0].inkey
|
|
)
|
|
if(data) {
|
|
this.formDialogSettings.data.custom_css = data.custom_css
|
|
}
|
|
} catch (error) {
|
|
LNbits.utils.notifyApiError(error)
|
|
}
|
|
},
|
|
|
|
sendFormDataSettings: function () {
|
|
const wallet = this.g.user.wallets[0].inkey
|
|
const data = this.formDialogSettings.data
|
|
data.custom_css = data.custom_css
|
|
this.saveSettings(wallet, data)
|
|
},
|
|
sendFormDataCharge: function () {
|
|
const wallet = this.g.user.wallets[0].inkey
|
|
const data = this.formDialogCharge.data
|
|
data.amount = parseInt(data.amount)
|
|
data.time = parseInt(data.time)
|
|
data.lnbitswallet = data.lnbits ? data.lnbitswallet : null
|
|
data.onchainwallet = data.onchain ? this.onchainwallet?.id : null
|
|
this.createCharge(wallet, data)
|
|
},
|
|
refreshActiveChargesBalance: async function () {
|
|
try {
|
|
const activeLinkIds = this.chargeLinks
|
|
.filter(c => !c.paid && !c.time_elapsed && !c.hasStaleBalance)
|
|
.map(c => c.id)
|
|
.join(',')
|
|
if (activeLinkIds) {
|
|
await LNbits.api.request(
|
|
'GET',
|
|
'/satspay/api/v1/charges/balance/' + activeLinkIds,
|
|
'filla'
|
|
)
|
|
}
|
|
} catch (error) {
|
|
LNbits.utils.notifyApiError(error)
|
|
} finally {
|
|
await this.getCharges()
|
|
}
|
|
},
|
|
refreshBalance: async function (charge) {
|
|
try {
|
|
const {data} = await LNbits.api.request(
|
|
'GET',
|
|
'/satspay/api/v1/charge/balance/' + charge.id,
|
|
'filla'
|
|
)
|
|
charge.balance = data.balance
|
|
} catch (error) {}
|
|
},
|
|
rescanOnchainAddresses: async function () {
|
|
if (this.rescanning) return
|
|
this.rescanning = true
|
|
|
|
const {
|
|
bitcoin: {addresses: addressesAPI}
|
|
} = mempoolJS({hostname: this.mempool.hostname})
|
|
|
|
try {
|
|
const onchainActiveCharges = this.chargeLinks.filter(
|
|
c => c.onchainaddress && !c.paid && !c.time_elapsed
|
|
)
|
|
for (const charge of onchainActiveCharges) {
|
|
const fn = async () =>
|
|
addressesAPI.getAddressTxsUtxo({
|
|
address: charge.onchainaddress
|
|
})
|
|
|
|
const utxos = await retryWithDelay(fn)
|
|
const newBalance = utxos.reduce((t, u) => t + u.value, 0)
|
|
|
|
charge.pendingBalance = utxos
|
|
.filter(u => !u.status.confirmed)
|
|
.reduce((t, u) => t + u.value, 0)
|
|
|
|
charge.hasStaleBalance = charge.balance === newBalance
|
|
}
|
|
} catch (error) {
|
|
console.error(error)
|
|
} finally {
|
|
this.rescanning = false
|
|
}
|
|
},
|
|
saveSettings: async function (wallet, data) {
|
|
try {
|
|
const resp = await LNbits.api.request(
|
|
'POST',
|
|
'/satspay/api/v1/settings',
|
|
wallet,
|
|
data
|
|
)
|
|
|
|
this.formDialogSettings.show = false
|
|
this.formDialogSettings.data = {
|
|
custom_css: ''
|
|
}
|
|
} catch (error) {
|
|
LNbits.utils.notifyApiError(error)
|
|
}
|
|
},
|
|
createCharge: async function (wallet, data) {
|
|
try {
|
|
const resp = await LNbits.api.request(
|
|
'POST',
|
|
'/satspay/api/v1/charge',
|
|
wallet,
|
|
data
|
|
)
|
|
|
|
this.chargeLinks.unshift(mapCharge(resp.data))
|
|
this.formDialogCharge.show = false
|
|
this.formDialogCharge.data = {
|
|
onchain: false,
|
|
lnbits: false,
|
|
description: '',
|
|
time: null,
|
|
amount: null
|
|
}
|
|
} catch (error) {
|
|
LNbits.utils.notifyApiError(error)
|
|
}
|
|
},
|
|
|
|
deleteChargeLink: function (chargeId) {
|
|
const link = _.findWhere(this.chargeLinks, {id: chargeId})
|
|
LNbits.utils
|
|
.confirmDialog('Are you sure you want to delete this pay link?')
|
|
.onOk(async () => {
|
|
try {
|
|
const response = await LNbits.api.request(
|
|
'DELETE',
|
|
'/satspay/api/v1/charge/' + chargeId,
|
|
this.g.user.wallets[0].adminkey
|
|
)
|
|
|
|
this.chargeLinks = _.reject(this.chargeLinks, function (obj) {
|
|
return obj.id === chargeId
|
|
})
|
|
} catch (error) {
|
|
LNbits.utils.notifyApiError(error)
|
|
}
|
|
})
|
|
},
|
|
exportchargeCSV: function () {
|
|
LNbits.utils.exportCSV(
|
|
this.chargesTable.columns,
|
|
this.chargeLinks,
|
|
'charges'
|
|
)
|
|
}
|
|
},
|
|
created: async function () {
|
|
await this.getSettings()
|
|
await this.getCharges()
|
|
await this.getWalletConfig()
|
|
await this.getWalletLinks()
|
|
setInterval(() => this.refreshActiveChargesBalance(), 10 * 2000)
|
|
await this.rescanOnchainAddresses()
|
|
setInterval(() => this.rescanOnchainAddresses(), 10 * 1000)
|
|
}
|
|
})
|
|
</script>
|
|
{% endblock %}
|