Use conditional waitFor to fix premature payment success
This commit is contained in:
parent
8cb89574ae
commit
4e6fb40c0b
|
@ -232,9 +232,15 @@ export function useAct ({ query = ACT_MUTATION, ...options } = {}) {
|
||||||
// because the mutation name we use varies,
|
// because the mutation name we use varies,
|
||||||
// we need to extract the result/invoice from the response
|
// we need to extract the result/invoice from the response
|
||||||
const getPaidActionResult = data => Object.values(data)[0]
|
const getPaidActionResult = data => Object.values(data)[0]
|
||||||
|
const wallets = useSendWallets()
|
||||||
|
|
||||||
const [act] = usePaidMutation(query, {
|
const [act] = usePaidMutation(query, {
|
||||||
waitFor: inv => inv?.satsReceived > 0,
|
waitFor: inv =>
|
||||||
|
// if we have attached wallets, we might be paying a wrapped invoice in which case we need to make sure
|
||||||
|
// we don't prematurely consider the payment as successful (important for receiver fallbacks)
|
||||||
|
wallets.length > 0
|
||||||
|
? inv?.actionState === 'PAID'
|
||||||
|
: inv?.satsReceived > 0,
|
||||||
...options,
|
...options,
|
||||||
update: (cache, { data }) => {
|
update: (cache, { data }) => {
|
||||||
const response = getPaidActionResult(data)
|
const response = getPaidActionResult(data)
|
||||||
|
|
|
@ -4,8 +4,6 @@ import { InvoiceCanceledError, InvoiceExpiredError, WalletReceiverError } from '
|
||||||
import { RETRY_PAID_ACTION } from '@/fragments/paidAction'
|
import { RETRY_PAID_ACTION } from '@/fragments/paidAction'
|
||||||
import { INVOICE, CANCEL_INVOICE } from '@/fragments/wallet'
|
import { INVOICE, CANCEL_INVOICE } from '@/fragments/wallet'
|
||||||
|
|
||||||
const PENDING_FORWARD_STATES = ['PENDING_HELD', 'FORWARDING']
|
|
||||||
|
|
||||||
export default function useInvoice () {
|
export default function useInvoice () {
|
||||||
const client = useApolloClient()
|
const client = useApolloClient()
|
||||||
const [retryPaidAction] = useMutation(RETRY_PAID_ACTION)
|
const [retryPaidAction] = useMutation(RETRY_PAID_ACTION)
|
||||||
|
@ -18,7 +16,7 @@ export default function useInvoice () {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
const { cancelled, cancelledAt, actionState, actionError, expiresAt, forwardStatus } = data.invoice
|
const { cancelled, cancelledAt, actionError, expiresAt, forwardStatus } = data.invoice
|
||||||
|
|
||||||
const expired = cancelledAt && new Date(expiresAt) < new Date(cancelledAt)
|
const expired = cancelledAt && new Date(expiresAt) < new Date(cancelledAt)
|
||||||
if (expired) {
|
if (expired) {
|
||||||
|
@ -35,12 +33,7 @@ export default function useInvoice () {
|
||||||
throw new InvoiceCanceledError(data.invoice, actionError)
|
throw new InvoiceCanceledError(data.invoice, actionError)
|
||||||
}
|
}
|
||||||
|
|
||||||
// never let check pass if a forward is pending
|
return { invoice: data.invoice, check: that(data.invoice) }
|
||||||
// see https://github.com/stackernews/stacker.news/issues/1707
|
|
||||||
const pendingForward = PENDING_FORWARD_STATES.includes(actionState)
|
|
||||||
const check = that(data.invoice) && !pendingForward
|
|
||||||
|
|
||||||
return { invoice: data.invoice, check }
|
|
||||||
}, [client])
|
}, [client])
|
||||||
|
|
||||||
const cancel = useCallback(async ({ hash, hmac }) => {
|
const cancel = useCallback(async ({ hash, hmac }) => {
|
||||||
|
|
Loading…
Reference in New Issue