Satspay mostly working
This commit is contained in:
parent
f5d06653a6
commit
90319bfd8c
|
@ -11,7 +11,6 @@ import httpx
|
|||
from lnbits.core.services import create_invoice, check_invoice_status
|
||||
from ..watchonly.crud import get_watch_wallet, get_derive_address, get_mempool
|
||||
|
||||
import time
|
||||
|
||||
###############CHARGES##########################
|
||||
|
||||
|
@ -45,13 +44,12 @@ async def create_charge(user: str, description: Optional[str] = None, onchainwal
|
|||
webhook,
|
||||
time,
|
||||
amount,
|
||||
balance,
|
||||
paid
|
||||
balance
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""",
|
||||
(charge_id, user, description, onchainwallet, onchainaddress, lnbitswallet,
|
||||
payment_request, payment_hash, webhook, time, amount, 0, False),
|
||||
payment_request, payment_hash, webhook, time, amount, 0),
|
||||
)
|
||||
return await get_charge(charge_id)
|
||||
|
||||
|
@ -79,21 +77,24 @@ async def delete_charge(charge_id: str) -> None:
|
|||
|
||||
async def check_address_balance(charge_id: str) -> List[Charges]:
|
||||
charge = await get_charge(charge_id)
|
||||
print(charge.balance)
|
||||
if not charge.paid:
|
||||
if charge.onchainaddress:
|
||||
mempool = await get_mempool(charge.user)
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.get(mempool.endpoint + "/api/address/" + charge.onchainaddress)
|
||||
respAmount = r.json()['chain_stats']['funded_txo_sum']
|
||||
if (charge.balance + respAmount) >= charge.balance:
|
||||
return await update_charge(charge_id=charge_id, balance=(charge.balance + respAmount), paid=True)
|
||||
else:
|
||||
return await update_charge(charge_id=charge_id, balance=(charge.balance + respAmount), paid=False)
|
||||
print(respAmount)
|
||||
if respAmount >= charge.balance:
|
||||
await update_charge(charge_id=charge_id, balance=respAmount)
|
||||
except Exception:
|
||||
pass
|
||||
if charge.lnbitswallet:
|
||||
invoice_status = await check_invoice_status(charge.lnbitswallet, charge.payment_hash)
|
||||
print(invoice_status)
|
||||
if invoice_status.paid:
|
||||
return await update_charge(charge_id=charge_id, balance=charge.balance, paid=True)
|
||||
print("paid")
|
||||
return await update_charge(charge_id=charge_id, balance=charge.amount)
|
||||
row = await db.fetchone("SELECT * FROM charges WHERE id = ?", (charge_id,))
|
||||
return Charges.from_row(row) if row else None
|
||||
|
|
|
@ -3,7 +3,6 @@ async def m001_initial(db):
|
|||
Initial wallet table.
|
||||
"""
|
||||
|
||||
|
||||
await db.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS charges (
|
||||
|
@ -19,7 +18,6 @@ async def m001_initial(db):
|
|||
time INTEGER,
|
||||
amount INTEGER,
|
||||
balance INTEGER DEFAULT 0,
|
||||
paid BOOLEAN,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now'))
|
||||
);
|
||||
"""
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from sqlite3 import Row
|
||||
from typing import NamedTuple
|
||||
import time
|
||||
|
||||
|
||||
class Charges(NamedTuple):
|
||||
|
@ -12,12 +13,25 @@ class Charges(NamedTuple):
|
|||
payment_request: str
|
||||
payment_hash: str
|
||||
webhook: str
|
||||
time: str
|
||||
time: int
|
||||
amount: int
|
||||
balance: int
|
||||
paid: bool
|
||||
timestamp: int
|
||||
|
||||
@classmethod
|
||||
def from_row(cls, row: Row) -> "Charges":
|
||||
return cls(**dict(row))
|
||||
|
||||
@property
|
||||
def time_elapsed(self):
|
||||
if (self.timestamp + (self.time * 60)) >= time.time():
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
@property
|
||||
def paid(self):
|
||||
if self.balance >= self.amount:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
|
|
@ -117,80 +117,6 @@
|
|||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="api"
|
||||
dense
|
||||
expand-separator
|
||||
label="Create a charge link"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code><span class="text-green">POST</span> /pay/api/v1/links</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||
<code>{"X-Api-Key": <invoice_key>}</code><br />
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
Body (application/json)
|
||||
</h5>
|
||||
<code>{"description": <string> "amount": <integer>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
Returns 201 CREATED (application/json)
|
||||
</h5>
|
||||
<code>
|
||||
{ "deliveryId": <string>, "description": <string>,
|
||||
"webhookId": <string>, "originalDeliveryId": <string>,
|
||||
"isRedelivery": <boolean>, "type": <string>,
|
||||
"timestamp": <int>, "paytime": <int>, "storeId":
|
||||
<string>, "invoiceId": <string>, "manuallyMarked":
|
||||
<boolean>, "overPaid": <boolean>, "afterExpiration":
|
||||
<boolean>, "partiallyPaid": <boolean> }<br /><small
|
||||
>"type" can be InvoiceReceivedPayment, InvoicePaidInFull,
|
||||
InvoiceExpired, InvoiceConfirmed, and InvoiceInvalid</small
|
||||
>
|
||||
</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X POST {{ request.url_root }}pay/api/v1/links -d
|
||||
'{"description": <string>, "amount": <integer>}' -H
|
||||
"Content-type: application/json" -H "X-Api-Key: {{
|
||||
g.user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="api"
|
||||
dense
|
||||
expand-separator
|
||||
label="Update a pay link"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code
|
||||
><span class="text-green">PUT</span>
|
||||
/pay/api/v1/links/<pay_id></code
|
||||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||
<code>{"X-Api-Key": <admin_key>}</code><br />
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
Body (application/json)
|
||||
</h5>
|
||||
<code
|
||||
>{"description": <string>, "amount": <integer>}</code
|
||||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
Returns 200 OK (application/json)
|
||||
</h5>
|
||||
<code>{"lnurl": <string>}</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X PUT {{ request.url_root }}pay/api/v1/links/<pay_id>
|
||||
-d '{"description": <string>, "amount": <integer>}' -H
|
||||
"Content-type: application/json" -H "X-Api-Key: {{
|
||||
g.user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="api"
|
||||
dense
|
||||
|
@ -202,7 +128,7 @@
|
|||
<q-card-section>
|
||||
<code
|
||||
><span class="text-pink">DELETE</span>
|
||||
/pay/api/v1/links/<pay_id></code
|
||||
/satspay/api/v1/charge/<charge_id></code
|
||||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||
<code>{"X-Api-Key": <admin_key>}</code><br />
|
||||
|
@ -211,11 +137,36 @@
|
|||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X DELETE {{ request.url_root
|
||||
}}pay/api/v1/links/<pay_id> -H "X-Api-Key: {{
|
||||
}}api/v1/charge/<charge_id> -H "X-Api-Key: {{
|
||||
g.user.wallets[0].adminkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item group="api" dense expand-separator label="Get balances">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<code
|
||||
><span class="text-blue">GET</span>
|
||||
/satspay/api/v1/charges/balance/<charge_id></code
|
||||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||
<code>{"X-Api-Key": <admin_key>}</code><br />
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
Body (application/json)
|
||||
</h5>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
Returns 200 OK (application/json)
|
||||
</h5>
|
||||
<code>[<charge_object>, ...]</code>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
|
||||
<code
|
||||
>curl -X GET {{ request.url_root
|
||||
}}api/v1/charges/balance/<charge_id> -H "X-Api-Key: {{
|
||||
g.user.wallets[0].inkey }}"
|
||||
</code>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
</q-expansion-item>
|
||||
</q-card>
|
||||
|
|
|
@ -1,74 +1,241 @@
|
|||
{% extends "public.html" %} {% block page %}
|
||||
|
||||
<div class="q-pa-md">
|
||||
<div class="q-pa-sm theCard">
|
||||
<q-card class="my-card">
|
||||
<q-card-section>
|
||||
<div class="text-h6">Our Changing Planet</div>
|
||||
<div class="text-subtitle2">by John Doe</div>
|
||||
<div class="column">
|
||||
<center> <div class="col theHeading">{{ charge.description }}</div></center>
|
||||
|
||||
<div class="col">
|
||||
<div class="col" color="white" style="background-color:grey; height: 30px; padding: 5px" v-if="charge_time_elapsed == 'True'">
|
||||
<center>Time elapsed</center>
|
||||
</div>
|
||||
<div class="col" color="white" style="background-color:grey; height: 30px; padding: 5px" v-else-if="charge_paid == 'True'">
|
||||
<center>Charge paid</center>
|
||||
</div>
|
||||
<div v-else>
|
||||
<q-linear-progress size="30px" :value="newProgress" color="grey" >
|
||||
|
||||
<q-item-section>
|
||||
<q-item style="padding: 3px">
|
||||
<q-spinner color="white" size="0.8em" ></q-spinner
|
||||
><span style="font-size: 15px; color:white"><span class="q-pr-xl q-pl-md"> Awaiting payment...</span>
|
||||
<span class="q-pl-xl" style="color:white"> {% raw %} {{ newTimeLeft }} {% endraw %}</span></span>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-linear-progress>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col" style="margin: 2px 15px; max-height:100px" >
|
||||
<center>
|
||||
<q-btn flat dense outline @click="copyText('{{ charge.id }}')"
|
||||
>Charge ID: {{ charge.id }}</q-btn
|
||||
>
|
||||
</center>
|
||||
<span><small>{% raw %}
|
||||
Total to pay: {{ charge_amount }}sats<br/>
|
||||
Amount paid: {{ charge_balance }}</small><br/>
|
||||
Amount due: {{ charge_amount - charge_balance }}sats
|
||||
{% endraw %}
|
||||
</span>
|
||||
</div>
|
||||
<q-separator></q-separator>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<q-btn flat disable v-if="'{{ charge.lnbitswallet }}' == 'None' || charge_time_elapsed == 'True'" style="color: primary; width: 100%" label="lightning⚡" >
|
||||
<q-tooltip>
|
||||
bitcoin onchain payment method not available
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn flat v-else @click="payLN" style="color: primary; width: 100%" label="lightning⚡" >
|
||||
<q-tooltip>
|
||||
pay with lightning
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-btn flat disable v-if="'{{ charge.onchainwallet }}' == 'None' || charge_time_elapsed == 'True'" style="color: primary; width: 100%" label="onchain⛓️" >
|
||||
<q-tooltip>
|
||||
bitcoin lightning payment method not available
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn flat v-else @click="payON" style="color: primary; width: 100%" label="onchain⛓️" >
|
||||
<q-tooltip>
|
||||
pay onchain
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
<q-separator></q-separator>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<q-card class="q-pa-lg" v-if="lnbtc">
|
||||
<q-card-section class="q-pa-none">
|
||||
<div class="text-center q-pt-md">
|
||||
<div v-if="charge_time_elapsed == 'True' && charge_paid == 'False'">
|
||||
|
||||
<q-icon name="block" style="color: #ccc; font-size: 21.4em;" ></q-icon>
|
||||
</div>
|
||||
<div v-else-if="charge_paid == 'True'">
|
||||
<q-icon name="check" style="color:green; font-size: 21.4em;" ></q-icon>
|
||||
</div>
|
||||
<div v-else>
|
||||
<center>
|
||||
<span class="text-subtitle2">Pay this <br/> lightning-network invoice</span>
|
||||
</center>
|
||||
<a href="lightning://{{ charge.payment_request }}">
|
||||
<q-responsive :ratio="1" class="q-mx-md">
|
||||
<qrcode
|
||||
:value="'{{ charge.payment_request }}'"
|
||||
:options="{width: 800}"
|
||||
class="rounded-borders"
|
||||
></qrcode>
|
||||
</q-responsive>
|
||||
</a>
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn outline color="grey" @click="copyText('{{ charge.payment_request }}')"
|
||||
>Copy invoice</q-btn
|
||||
>
|
||||
</div>
|
||||
</div></div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
||||
<q-tabs v-model="tab" class="text-teal">
|
||||
<q-tab label="Tab one" name="one" />
|
||||
<q-tab label="Tab two" name="two" />
|
||||
</q-tabs>
|
||||
|
||||
<q-separator />
|
||||
<q-card class="q-pa-lg" v-if="onbtc">
|
||||
<q-card-section class="q-pa-none">
|
||||
|
||||
<q-tab-panels v-model="tab" animated>
|
||||
<q-tab-panel name="Lightning">
|
||||
<div class="text-center">
|
||||
<a href="lightning:{{ charge.id }}">
|
||||
<div class="text-center q-pt-md">
|
||||
<div v-if="charge_time_elapsed == 'True' && charge_paid == 'False'">
|
||||
|
||||
<q-icon name="block" style="color: #ccc; font-size: 21.4em;" ></q-icon>
|
||||
</div>
|
||||
<div v-else-if="charge_paid == 'True'">
|
||||
<q-icon name="check" style="color:green; font-size: 21.4em;" ></q-icon>
|
||||
</div>
|
||||
<div v-else>
|
||||
<center>
|
||||
<span class="text-subtitle2">Send {{ charge.amount }}sats<br/> to this onchain address</span>
|
||||
</center>
|
||||
<a href="bitcoin://{{ charge.onchainaddress }}">
|
||||
<q-responsive :ratio="1" class="q-mx-md">
|
||||
<qrcode
|
||||
value="{{ charge.id }}"
|
||||
:options="{width: 300}"
|
||||
:value="'{{ charge.onchainaddress }}'"
|
||||
:options="{width: 800}"
|
||||
class="rounded-borders"
|
||||
></qrcode>
|
||||
</q-responsive>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn outline color="grey" @click="copyText('{{ charge.id }}')"
|
||||
<q-btn outline color="grey" @click="copyText('{{ charge.onchainaddress }}')"
|
||||
>Copy address</q-btn
|
||||
>
|
||||
</div>
|
||||
</q-tab-panel>
|
||||
|
||||
<q-tab-panel name="Onchain">
|
||||
<div class="text-center">
|
||||
<a href="lightning:{{ charge.id }}">
|
||||
<q-responsive :ratio="1" class="q-mx-md">
|
||||
<qrcode
|
||||
value="{{ charge.id }}"
|
||||
:options="{width: 300}"
|
||||
class="rounded-borders"
|
||||
></qrcode>
|
||||
</q-responsive>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn outline color="grey" @click="copyText('{{ charge.id }}')"
|
||||
>Copy address</q-btn
|
||||
>
|
||||
</div>
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</div></div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-card>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %} {% block scripts %}
|
||||
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
|
||||
<style>
|
||||
.theCard {
|
||||
width: 360px;
|
||||
margin: 10px auto;
|
||||
}
|
||||
.theHeading {
|
||||
margin: 15px;
|
||||
font-size: 25px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
Vue.component(VueQrcode.name, VueQrcode)
|
||||
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
mixins: [windowMixin]
|
||||
mixins: [windowMixin],
|
||||
data() {
|
||||
return {
|
||||
newProgress: 0.4,
|
||||
counter: 1,
|
||||
newTimeLeft: '',
|
||||
lnbtc: true,
|
||||
onbtc: false,
|
||||
charge_time_elapsed: '{{charge.time_elapsed}}',
|
||||
charge_amount: '{{charge.amount}}',
|
||||
charge_balance: '{{charge.balance}}',
|
||||
charge_paid: '{{charge.paid}}'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
checkBalance: function () {
|
||||
var self = this
|
||||
LNbits.api
|
||||
.request(
|
||||
'GET',
|
||||
'/satspay/api/v1/charges/balance/{{ charge.id }}',
|
||||
"filla"
|
||||
)
|
||||
.then(function (response) {
|
||||
console.log(response.data)
|
||||
self.charge_time_elapsed = response.data.time_elapsed
|
||||
self.charge_amount = response.data.amount
|
||||
self.charge_balance = response.data.balance
|
||||
if (self.charge_balance >= self.charge_amount ){
|
||||
self.charge_paid = "True"
|
||||
}
|
||||
console.log(self.charge_paid)
|
||||
})
|
||||
.catch(function (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
})
|
||||
},
|
||||
payLN: function(){
|
||||
this.lnbtc = true
|
||||
this.onbtc = false
|
||||
},
|
||||
payON: function(){
|
||||
this.lnbtc = false
|
||||
this.onbtc = true
|
||||
},
|
||||
getTheTime: function () {
|
||||
var timeToComplete = (parseInt('{{ charge.time }}') * 60) - (Date.now()/1000 - parseInt('{{ charge.timestamp }}') )
|
||||
var timeLeft = Quasar.utils.date.formatDate(
|
||||
new Date((timeToComplete - 3600)*1000),
|
||||
'HH:mm:ss'
|
||||
)
|
||||
this.newTimeLeft = timeLeft
|
||||
},
|
||||
getThePercentage: function () {
|
||||
var timeToComplete = (parseInt('{{ charge.time }}') * 60) - (Date.now()/1000 - parseInt('{{ charge.timestamp }}') )
|
||||
this.newProgress = 1 - (timeToComplete / (parseInt('{{ charge.time }}') * 60))
|
||||
},
|
||||
|
||||
timerCount: function () {
|
||||
self = this
|
||||
setInterval(function () {
|
||||
self.getTheTime()
|
||||
self.getThePercentage()
|
||||
self.counter++
|
||||
if (self.counter% 10 === 0){
|
||||
self.checkBalance()
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
},
|
||||
created: function () {
|
||||
this.getTheTime()
|
||||
this.getThePercentage()
|
||||
var timerCount = this.timerCount
|
||||
console.log('{{ charge.paid }}')
|
||||
if('{{ charge.paid }}' == 'False'){
|
||||
timerCount()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -64,33 +64,53 @@
|
|||
type="a"
|
||||
:href="props.row.displayUrl"
|
||||
target="_blank"
|
||||
></q-btn>
|
||||
>
|
||||
<q-tooltip>
|
||||
Payment link
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</q-td>
|
||||
<q-td auto-width>
|
||||
|
||||
<q-icon v-if="props.row.timeleft < 1 && props.row.amount_paid < props.row.amount"
|
||||
#unelevated
|
||||
<q-btn v-if="props.row.time_elapsed && props.row.balance < props.row.amount"
|
||||
unelevated
|
||||
flat
|
||||
dense
|
||||
size="xs"
|
||||
name="error"
|
||||
icon="error"
|
||||
:color="($q.dark.isActive) ? 'red' : 'red'"
|
||||
></q-icon>
|
||||
>
|
||||
<q-tooltip>
|
||||
Time elapsed
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
|
||||
<q-icon v-else-if="props.row.balance > props.row.amount"
|
||||
#unelevated
|
||||
<q-btn v-else-if="props.row.balance >= props.row.amount"
|
||||
unelevated
|
||||
flat
|
||||
dense
|
||||
size="xs"
|
||||
name="check"
|
||||
icon="check"
|
||||
:color="($q.dark.isActive) ? 'green' : 'green'"
|
||||
></q-icon>
|
||||
>
|
||||
<q-tooltip>
|
||||
PAID!
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
|
||||
<q-icon v-else="props.row.amount_paid < props.row.amount && props.row.timeleft > 1"
|
||||
#unelevated
|
||||
<q-btn v-else
|
||||
unelevated
|
||||
dense
|
||||
size="xs"
|
||||
name="cached"
|
||||
icon="cached"
|
||||
flat
|
||||
@click="getBalance(props.row.id)"
|
||||
:color="($q.dark.isActive) ? 'blue' : 'blue'"
|
||||
></q-icon>
|
||||
>
|
||||
<q-tooltip>
|
||||
Check balance
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
|
@ -175,7 +195,8 @@
|
|||
dense
|
||||
v-model.trim="formDialogCharge.data.time"
|
||||
type="number"
|
||||
label="Time (secs)"
|
||||
max="1440"
|
||||
label="Mins valid for (max 1440)"
|
||||
> </q-input>
|
||||
|
||||
<q-input
|
||||
|
@ -281,26 +302,27 @@
|
|||
)
|
||||
return obj
|
||||
}
|
||||
var mapCharge = function (obj) {
|
||||
|
||||
var mapCharge = obj => {
|
||||
obj._data = _.clone(obj)
|
||||
obj.theDate = ( obj.time + obj.timestamp - ((Date.now()/1000)))
|
||||
console.log(obj.theDate)
|
||||
if(obj.theDate < 0){
|
||||
obj.theTime = (obj.time * 60) - (Date.now()/1000 - obj.timestamp)
|
||||
console.log(obj.theTime)
|
||||
obj.time = obj.time + "mins"
|
||||
|
||||
if(obj.time_elapsed){
|
||||
obj.date = "Time elapsed"
|
||||
}
|
||||
else{
|
||||
obj.date = Quasar.utils.date.formatDate(
|
||||
|
||||
new Date(obj.theDate * 1000),
|
||||
new Date((obj.theTime - 3600)*1000),
|
||||
'HH:mm:ss'
|
||||
)
|
||||
}
|
||||
|
||||
)}
|
||||
obj.displayUrl = ['/satspay/', obj.id].join('')
|
||||
|
||||
console.log(obj.date)
|
||||
return obj
|
||||
}
|
||||
|
||||
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
mixins: [windowMixin],
|
||||
|
@ -327,7 +349,7 @@
|
|||
columns: [
|
||||
|
||||
{
|
||||
name: 'id',
|
||||
name: 'theId',
|
||||
align: 'left',
|
||||
label: 'ID',
|
||||
field: 'id'
|
||||
|
@ -344,6 +366,12 @@
|
|||
label: 'Time left',
|
||||
field: 'date'
|
||||
},
|
||||
{
|
||||
name: 'time to pay',
|
||||
align: 'left',
|
||||
label: 'Time to Pay',
|
||||
field: 'time'
|
||||
},
|
||||
{
|
||||
name: 'amount',
|
||||
align: 'left',
|
||||
|
@ -356,12 +384,6 @@
|
|||
label: 'Balance',
|
||||
field: 'balance'
|
||||
},
|
||||
{
|
||||
name: 'time to pay',
|
||||
align: 'left',
|
||||
label: 'Time to Pay',
|
||||
field: 'time'
|
||||
},
|
||||
{
|
||||
name: 'onchain address',
|
||||
align: 'left',
|
||||
|
@ -394,11 +416,6 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
updateCountdowns: function () {
|
||||
setInterval(function(){
|
||||
|
||||
}, 1000)
|
||||
},
|
||||
|
||||
getWalletLinks: function () {
|
||||
var self = this
|
||||
|
@ -410,13 +427,9 @@
|
|||
this.g.user.wallets[0].inkey
|
||||
)
|
||||
.then(function (response) {
|
||||
console.log(response.data)
|
||||
for (i = 0; i < response.data.length; i++) {
|
||||
self.walletLinks.push(response.data[i].id)
|
||||
}
|
||||
console.log(self.walletLinks)
|
||||
|
||||
|
||||
return
|
||||
})
|
||||
.catch(function (error) {
|
||||
|
@ -463,25 +476,8 @@
|
|||
this.g.user.wallets[0].inkey
|
||||
)
|
||||
.then(function (response) {
|
||||
console.log(response.data)
|
||||
var i
|
||||
var now = parseInt(new Date() / 1000)
|
||||
for (i = 0; i < response.data.length; i++) {
|
||||
timeleft = response.data[i].time_to_pay - (now - response.data[i].time)
|
||||
if (timeleft < 1) {
|
||||
response.data[i].timeleft = 0
|
||||
}
|
||||
else{
|
||||
response.data[i].timeleft = timeleft
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
self.ChargeLinks = response.data.map(function (obj) {
|
||||
|
||||
|
||||
return mapCharge(obj)
|
||||
})
|
||||
console.log(response.data[0].time_elapsed)
|
||||
self.ChargeLinks = response.data.map(mapCharge)
|
||||
})
|
||||
.catch(function (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
|
@ -491,7 +487,6 @@
|
|||
var self = this
|
||||
var wallet = self.g.user.wallets[0].adminkey
|
||||
var data = self.formDialogCharge.data
|
||||
console.log(data)
|
||||
data.amount = parseInt(data.amount)
|
||||
data.time = parseInt(data.time)
|
||||
if (data.id) {
|
||||
|
@ -509,7 +504,7 @@
|
|||
LNbits.api
|
||||
.request(
|
||||
'PUT',
|
||||
'/satspay/api/v1/Charge/' + data.id,
|
||||
'/satspay/api/v1/charge/' + data.id,
|
||||
wallet.adminkey, data)
|
||||
.then(function (response) {
|
||||
self.Charge = _.reject(self.Charge, function (obj) {
|
||||
|
@ -531,7 +526,7 @@
|
|||
this.g.user.wallets[0].inkey
|
||||
)
|
||||
.then(function (response) {
|
||||
console.log(response.data)
|
||||
this.ChargeLinks = response.data.map(mapCharge)
|
||||
})
|
||||
.catch(function (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
|
@ -556,14 +551,13 @@
|
|||
deleteCharge: function (linkId) {
|
||||
var self = this
|
||||
var link = _.findWhere(this.Charge, {id: linkId})
|
||||
console.log(self.g.user.wallets[0].adminkey)
|
||||
LNbits.utils
|
||||
.confirmDialog('Are you sure you want to delete this pay link?')
|
||||
.onOk(function () {
|
||||
LNbits.api
|
||||
.request(
|
||||
'DELETE',
|
||||
'/satspay/api/v1/Charge/' + linkId,
|
||||
'/satspay/api/v1/charge/' + linkId,
|
||||
self.g.user.wallets[0].inkey
|
||||
)
|
||||
.then(function (response) {
|
||||
|
@ -603,7 +597,6 @@
|
|||
.then(function (response) {
|
||||
self.walletLinks.push(mapWalletLink(response.data))
|
||||
self.formDialog.show = false
|
||||
console.log(response.data[1][1])
|
||||
})
|
||||
.catch(function (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
|
@ -612,7 +605,6 @@
|
|||
deleteWalletLink: function (linkId) {
|
||||
var self = this
|
||||
var link = _.findWhere(this.walletLinks, {id: linkId})
|
||||
console.log(self.g.user.wallets[0].adminkey)
|
||||
LNbits.utils
|
||||
.confirmDialog('Are you sure you want to delete this pay link?')
|
||||
.onOk(function () {
|
||||
|
@ -642,15 +634,6 @@
|
|||
getCharges()
|
||||
var getWalletLinks = this.getWalletLinks
|
||||
getWalletLinks()
|
||||
var getBalance = this.getBalance
|
||||
setTimeout(function(){
|
||||
for (i = 0; i < self.ChargeLinks.length; i++) {
|
||||
getBalance(self.ChargeLinks[i].id)
|
||||
}
|
||||
}, 5000);
|
||||
getCharges()
|
||||
var updateCountdowns = this.updateCountdowns
|
||||
updateCountdowns()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from quart import g, abort, render_template
|
||||
from quart import g, abort, render_template, jsonify
|
||||
from http import HTTPStatus
|
||||
|
||||
from lnbits.decorators import check_user_exists, validate_uuids
|
||||
|
@ -16,6 +16,6 @@ async def index():
|
|||
|
||||
@satspay_ext.route("/<charge_id>")
|
||||
async def display(charge_id):
|
||||
charge = get_charge(charge_id) or abort(HTTPStatus.NOT_FOUND, "Charge link does not exist.")
|
||||
|
||||
charge = await get_charge(charge_id) or abort(
|
||||
HTTPStatus.NOT_FOUND, "Charge link does not exist.")
|
||||
return await render_template("satspay/display.html", charge=charge)
|
|
@ -46,38 +46,32 @@ async def api_charge_create_or_update(charge_id=None):
|
|||
@satspay_ext.route("/api/v1/charges", methods=["GET"])
|
||||
@api_check_wallet_key("invoice")
|
||||
async def api_charges_retrieve():
|
||||
|
||||
charges = await get_charges(g.wallet.user)
|
||||
if not charges:
|
||||
return (
|
||||
jsonify(""),
|
||||
HTTPStatus.OK
|
||||
)
|
||||
else:
|
||||
return jsonify([charge._asdict() for charge in charges]), HTTPStatus.OK
|
||||
try:
|
||||
return jsonify([{**charge._asdict(), **{"time_elapsed": charge.time_elapsed}, **{"paid": charge.paid}}for charge in await get_charges(g.wallet.user)]), HTTPStatus.OK
|
||||
except:
|
||||
return ""
|
||||
|
||||
|
||||
@satspay_ext.route("/api/v1/charge/<charge_id>", methods=["GET"])
|
||||
@api_check_wallet_key("invoice")
|
||||
async def api_charge_retrieve(charge_id):
|
||||
charge = await get_charge(charge_id)
|
||||
print(charge)
|
||||
|
||||
if not charge:
|
||||
return jsonify({"message": "charge does not exist"}), HTTPStatus.NOT_FOUND
|
||||
|
||||
return jsonify(charge._asdict()), HTTPStatus.OK
|
||||
return jsonify({**charge._asdict(), **{"time_elapsed": charge.time_elapsed}, **{"paid": charge.paid}}), HTTPStatus.OK
|
||||
|
||||
|
||||
@satspay_ext.route("/api/v1/charge/<charge_id>", methods=["DELETE"])
|
||||
@api_check_wallet_key("invoice")
|
||||
async def api_charge_delete(charge_id):
|
||||
charge = await get_watch_wallet(charge_id)
|
||||
charge = await get_charge(charge_id)
|
||||
|
||||
if not charge:
|
||||
return jsonify({"message": "Wallet link does not exist."}), HTTPStatus.NOT_FOUND
|
||||
|
||||
await delete_watch_wallet(charge_id)
|
||||
await delete_charge(charge_id)
|
||||
|
||||
return "", HTTPStatus.NO_CONTENT
|
||||
|
||||
|
@ -85,15 +79,12 @@ async def api_charge_delete(charge_id):
|
|||
#############################BALANCE##########################
|
||||
|
||||
@satspay_ext.route("/api/v1/charges/balance/<charge_id>", methods=["GET"])
|
||||
@api_check_wallet_key("invoice")
|
||||
async def api_charges_balance(charge_id):
|
||||
|
||||
charge = await check_address_balance(charge_id)
|
||||
|
||||
if not charge:
|
||||
return (
|
||||
jsonify(""),
|
||||
HTTPStatus.OK
|
||||
)
|
||||
return jsonify({"message": "charge does not exist"}), HTTPStatus.NOT_FOUND
|
||||
else:
|
||||
return jsonify(charge._asdict()), HTTPStatus.OK
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user