check pending payments and invoices on startup.

This commit is contained in:
fiatjaf 2019-12-15 20:24:37 +00:00
parent ad1c561862
commit 7616b4ec89
3 changed files with 57 additions and 3 deletions

View File

@ -336,3 +336,34 @@ def api_checkinvoice(payhash):
db.execute("UPDATE apipayments SET pending = 0 WHERE payhash = ?", (payhash,)) db.execute("UPDATE apipayments SET pending = 0 WHERE payhash = ?", (payhash,))
return jsonify({"PAID": "TRUE"}), 200 return jsonify({"PAID": "TRUE"}), 200
@app.route("/v1/checkpending", methods=["POST"])
def api_checkpending():
with Database() as db:
for pendingtx in db.fetchall("""
SELECT
payhash,
CASE
WHEN amount < 0 THEN 'send'
ELSE 'recv'
END AS kind
FROM apipayments
INNER JOIN wallets ON apipayments.wallet = wallets.id
WHERE time > strftime('%s', 'now') - 86400
AND pending = 1
AND (adminkey = ? OR inkey = ?)
""", (request.headers["Grpc-Metadata-macaroon"], request.headers["Grpc-Metadata-macaroon"])):
payhash = pendingtx['payhash']
kind = pendingtx['kind']
if kind == 'send':
status = WALLET.get_final_payment_status(payhash)
if status == 'complete':
db.execute("UPDATE apipayments SET pending = 0 WHERE payhash = ?", (payhash,))
elif status == 'failed':
db.execute("DELETE FROM apipayments WHERE payhash = ?", (payhash,))
elif kind == 'recv':
if WALLET.is_invoice_paid(payhash):
db.execute("UPDATE apipayments SET pending = 0 WHERE payhash = ?", (payhash,))
return ''

View File

@ -347,3 +347,7 @@ function convertTimestamp(timestamp) {
if (transactions.length) { if (transactions.length) {
drawChart(transactions) drawChart(transactions)
} }
if (wallet) {
postAjax('/v1/checkpending', '', wallet.adminkey, function(data) {})
}

View File

@ -19,7 +19,7 @@ class Wallet(ABC):
pass pass
@abstractmethod @abstractmethod
def get_invoice_status(self, payment_hash: str) -> WalletResponse: def get_invoice_status(self, payment_hash: str, wait: bool = True) -> WalletResponse:
pass pass
@ -42,5 +42,24 @@ class LntxbotWallet(Wallet):
def pay_invoice(self, bolt11: str) -> WalletResponse: def pay_invoice(self, bolt11: str) -> WalletResponse:
return requests.post(url=f"{self.endpoint}/payinvoice", headers=self.auth_admin, json={"invoice": bolt11}) return requests.post(url=f"{self.endpoint}/payinvoice", headers=self.auth_admin, json={"invoice": bolt11})
def get_invoice_status(self, payment_hash: str) -> Response: def get_invoice_status(self, payment_hash: str, wait: bool = True) -> Response:
return requests.post(url=f"{self.endpoint}/invoicestatus/{payment_hash}", headers=self.auth_invoice) wait = 'true' if wait else 'false'
return requests.post(url=f"{self.endpoint}/invoicestatus/{payment_hash}?wait={wait}", headers=self.auth_invoice)
def is_invoice_paid(self, payment_hash: str) -> False:
r = self.get_invoice_status(payment_hash)
if not r.ok or r.json().get('error'):
return False
data = r.json()
if "preimage" not in data or not data["preimage"]:
return False
return True
def get_final_payment_status(self, payment_hash: str) -> str:
r = requests.post(url=f"{self.endpoint}/paymentstatus/{payment_hash}", headers=self.auth_invoice)
if not r.ok:
return "unknown"
return r.json().get('status', 'unknown')