fix invoice waiting
This commit is contained in:
parent
e9a5925c50
commit
dcab8e1365
@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useMemo } from 'react'
|
import { useCallback } from 'react'
|
||||||
import { useMe } from './me'
|
import { useMe } from './me'
|
||||||
import { gql, useApolloClient, useMutation } from '@apollo/client'
|
import { gql, useApolloClient, useMutation } from '@apollo/client'
|
||||||
import { useWallet } from '@/wallets/index'
|
import { useWallet } from '@/wallets/index'
|
||||||
@ -60,43 +60,6 @@ export const useInvoice = () => {
|
|||||||
return that(data.invoice)
|
return that(data.invoice)
|
||||||
}, [client])
|
}, [client])
|
||||||
|
|
||||||
const waitController = useMemo(() => {
|
|
||||||
const controller = new AbortController()
|
|
||||||
const signal = controller.signal
|
|
||||||
controller.wait = async ({ id }, waitFor = inv => inv?.actionState === 'PAID') => {
|
|
||||||
return await new Promise((resolve, reject) => {
|
|
||||||
const interval = setInterval(async () => {
|
|
||||||
try {
|
|
||||||
const paid = await isInvoice({ id }, waitFor)
|
|
||||||
if (paid) {
|
|
||||||
resolve()
|
|
||||||
clearInterval(interval)
|
|
||||||
signal.removeEventListener('abort', abort)
|
|
||||||
} else {
|
|
||||||
console.info(`invoice #${id}: waiting for payment ...`)
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
reject(err)
|
|
||||||
clearInterval(interval)
|
|
||||||
signal.removeEventListener('abort', abort)
|
|
||||||
}
|
|
||||||
}, FAST_POLL_INTERVAL)
|
|
||||||
|
|
||||||
const abort = () => {
|
|
||||||
console.info(`invoice #${id}: stopped waiting`)
|
|
||||||
resolve()
|
|
||||||
clearInterval(interval)
|
|
||||||
signal.removeEventListener('abort', abort)
|
|
||||||
}
|
|
||||||
signal.addEventListener('abort', abort)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
controller.stop = () => controller.abort()
|
|
||||||
|
|
||||||
return controller
|
|
||||||
}, [isInvoice])
|
|
||||||
|
|
||||||
const cancel = useCallback(async ({ hash, hmac }) => {
|
const cancel = useCallback(async ({ hash, hmac }) => {
|
||||||
if (!hash || !hmac) {
|
if (!hash || !hmac) {
|
||||||
throw new Error('missing hash or hmac')
|
throw new Error('missing hash or hmac')
|
||||||
@ -107,7 +70,44 @@ export const useInvoice = () => {
|
|||||||
return inv
|
return inv
|
||||||
}, [cancelInvoice])
|
}, [cancelInvoice])
|
||||||
|
|
||||||
return { create, waitUntilPaid: waitController.wait, stopWaiting: waitController.stop, cancel }
|
return { create, cancel, isInvoice }
|
||||||
|
}
|
||||||
|
|
||||||
|
const invoiceController = (id, isInvoice) => {
|
||||||
|
const controller = new AbortController()
|
||||||
|
const signal = controller.signal
|
||||||
|
controller.wait = async (waitFor = inv => inv?.actionState === 'PAID') => {
|
||||||
|
return await new Promise((resolve, reject) => {
|
||||||
|
const interval = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
const paid = await isInvoice({ id }, waitFor)
|
||||||
|
if (paid) {
|
||||||
|
resolve()
|
||||||
|
clearInterval(interval)
|
||||||
|
signal.removeEventListener('abort', abort)
|
||||||
|
} else {
|
||||||
|
console.info(`invoice #${id}: waiting for payment ...`)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
reject(err)
|
||||||
|
clearInterval(interval)
|
||||||
|
signal.removeEventListener('abort', abort)
|
||||||
|
}
|
||||||
|
}, FAST_POLL_INTERVAL)
|
||||||
|
|
||||||
|
const abort = () => {
|
||||||
|
console.info(`invoice #${id}: stopped waiting`)
|
||||||
|
resolve()
|
||||||
|
clearInterval(interval)
|
||||||
|
signal.removeEventListener('abort', abort)
|
||||||
|
}
|
||||||
|
signal.addEventListener('abort', abort)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.stop = () => controller.abort()
|
||||||
|
|
||||||
|
return controller
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useWalletPayment = () => {
|
export const useWalletPayment = () => {
|
||||||
@ -118,12 +118,13 @@ export const useWalletPayment = () => {
|
|||||||
if (!wallet) {
|
if (!wallet) {
|
||||||
throw new NoAttachedWalletError()
|
throw new NoAttachedWalletError()
|
||||||
}
|
}
|
||||||
|
const controller = invoiceController(id, invoice.isInvoice)
|
||||||
try {
|
try {
|
||||||
return await new Promise((resolve, reject) => {
|
return await new Promise((resolve, reject) => {
|
||||||
// can't use await here since we might pay JIT invoices and sendPaymentAsync is not supported yet.
|
// can't use await here since we might pay JIT invoices and sendPaymentAsync is not supported yet.
|
||||||
// see https://www.webln.guide/building-lightning-apps/webln-reference/webln.sendpaymentasync
|
// see https://www.webln.guide/building-lightning-apps/webln-reference/webln.sendpaymentasync
|
||||||
wallet.sendPayment(bolt11).catch(reject)
|
wallet.sendPayment(bolt11).catch(reject)
|
||||||
invoice.waitUntilPaid({ id }, waitFor)
|
controller.wait(waitFor)
|
||||||
.then(resolve)
|
.then(resolve)
|
||||||
.catch(reject)
|
.catch(reject)
|
||||||
})
|
})
|
||||||
@ -131,7 +132,7 @@ export const useWalletPayment = () => {
|
|||||||
console.error('payment failed:', err)
|
console.error('payment failed:', err)
|
||||||
throw err
|
throw err
|
||||||
} finally {
|
} finally {
|
||||||
invoice.stopWaiting()
|
controller.stop()
|
||||||
}
|
}
|
||||||
}, [wallet, invoice])
|
}, [wallet, invoice])
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user