Fix missing item invoice update for optimistic actions
This commit is contained in:
		
							parent
							
								
									0051c82415
								
							
						
					
					
						commit
						a4144d4fcc
					
				@ -24,15 +24,15 @@ export const useInvoice = () => {
 | 
				
			|||||||
      throw error
 | 
					      throw error
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const { hash, cancelled, cancelledAt, actionError, actionState, expiresAt } = data.invoice
 | 
					    const { cancelled, cancelledAt, actionError, actionState, expiresAt } = data.invoice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const expired = cancelledAt && new Date(expiresAt) < new Date(cancelledAt)
 | 
					    const expired = cancelledAt && new Date(expiresAt) < new Date(cancelledAt)
 | 
				
			||||||
    if (expired) {
 | 
					    if (expired) {
 | 
				
			||||||
      throw new InvoiceExpiredError(hash)
 | 
					      throw new InvoiceExpiredError(data.invoice)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (cancelled || actionError) {
 | 
					    if (cancelled || actionError) {
 | 
				
			||||||
      throw new InvoiceCanceledError(hash, actionError)
 | 
					      throw new InvoiceCanceledError(data.invoice, actionError)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // write to cache if paid
 | 
					    // write to cache if paid
 | 
				
			||||||
@ -84,7 +84,7 @@ export const useQrPayment = () => {
 | 
				
			|||||||
      const cancelAndReject = async (onClose) => {
 | 
					      const cancelAndReject = async (onClose) => {
 | 
				
			||||||
        if (!paid && cancelOnClose) {
 | 
					        if (!paid && cancelOnClose) {
 | 
				
			||||||
          await invoice.cancel(inv).catch(console.error)
 | 
					          await invoice.cancel(inv).catch(console.error)
 | 
				
			||||||
          reject(new InvoiceCanceledError(inv?.hash))
 | 
					          reject(new InvoiceCanceledError(inv))
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        resolve(inv)
 | 
					        resolve(inv)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@ -97,8 +97,8 @@ export const useQrPayment = () => {
 | 
				
			|||||||
          successVerb='received'
 | 
					          successVerb='received'
 | 
				
			||||||
          walletError={walletError}
 | 
					          walletError={walletError}
 | 
				
			||||||
          waitFor={waitFor}
 | 
					          waitFor={waitFor}
 | 
				
			||||||
          onExpired={inv => reject(new InvoiceExpiredError(inv?.hash))}
 | 
					          onExpired={inv => reject(new InvoiceExpiredError(inv))}
 | 
				
			||||||
          onCanceled={inv => { onClose(); reject(new InvoiceCanceledError(inv?.hash, inv?.actionError)) }}
 | 
					          onCanceled={inv => { onClose(); reject(new InvoiceCanceledError(inv, inv?.actionError)) }}
 | 
				
			||||||
          onPayment={() => { paid = true; onClose(); resolve(inv) }}
 | 
					          onPayment={() => { paid = true; onClose(); resolve(inv) }}
 | 
				
			||||||
          poll
 | 
					          poll
 | 
				
			||||||
        />,
 | 
					        />,
 | 
				
			||||||
 | 
				
			|||||||
@ -107,6 +107,20 @@ export function usePaidMutation (mutation,
 | 
				
			|||||||
          onPaid?.(client.cache, { data })
 | 
					          onPaid?.(client.cache, { data })
 | 
				
			||||||
        }).catch(e => {
 | 
					        }).catch(e => {
 | 
				
			||||||
          console.error('usePaidMutation: failed to pay invoice', e)
 | 
					          console.error('usePaidMutation: failed to pay invoice', e)
 | 
				
			||||||
 | 
					          if (e.invoice) {
 | 
				
			||||||
 | 
					            // update the failed invoice for the Apollo cache update
 | 
				
			||||||
 | 
					            data = {
 | 
				
			||||||
 | 
					              [Object.keys(data)[0]]: {
 | 
				
			||||||
 | 
					                ...data,
 | 
				
			||||||
 | 
					                invoice: {
 | 
				
			||||||
 | 
					                  ...e.invoice,
 | 
				
			||||||
 | 
					                  actionState: 'FAILED',
 | 
				
			||||||
 | 
					                  cancelled: true,
 | 
				
			||||||
 | 
					                  cancelledAt: new Date()
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          // onPayError is called after the invoice fails to pay
 | 
					          // onPayError is called after the invoice fails to pay
 | 
				
			||||||
          // useful for updating invoiceActionState to FAILED
 | 
					          // useful for updating invoiceActionState to FAILED
 | 
				
			||||||
          onPayError?.(e, client.cache, { data })
 | 
					          onPayError?.(e, client.cache, { data })
 | 
				
			||||||
 | 
				
			|||||||
@ -1,16 +1,17 @@
 | 
				
			|||||||
export class InvoiceCanceledError extends Error {
 | 
					export class InvoiceCanceledError extends Error {
 | 
				
			||||||
  constructor (hash, actionError) {
 | 
					  constructor (invoice, actionError) {
 | 
				
			||||||
    super(actionError ?? `invoice canceled: ${hash}`)
 | 
					    super(actionError ?? `invoice canceled: ${invoice.hash}`)
 | 
				
			||||||
    this.name = 'InvoiceCanceledError'
 | 
					    this.name = 'InvoiceCanceledError'
 | 
				
			||||||
    this.hash = hash
 | 
					    this.invoice = invoice
 | 
				
			||||||
    this.actionError = actionError
 | 
					    this.actionError = actionError
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class InvoiceExpiredError extends Error {
 | 
					export class InvoiceExpiredError extends Error {
 | 
				
			||||||
  constructor (hash) {
 | 
					  constructor (invoice) {
 | 
				
			||||||
    super(`invoice expired: ${hash}`)
 | 
					    super(`invoice expired: ${invoice.hash}`)
 | 
				
			||||||
    this.name = 'InvoiceExpiredError'
 | 
					    this.name = 'InvoiceExpiredError'
 | 
				
			||||||
 | 
					    this.invoice = invoice
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,7 @@ export async function sendPayment (bolt11, credentials, { logger }) {
 | 
				
			|||||||
      return preimage
 | 
					      return preimage
 | 
				
			||||||
    } catch (err) {
 | 
					    } catch (err) {
 | 
				
			||||||
      const msg = err.message || err.toString?.()
 | 
					      const msg = err.message || err.toString?.()
 | 
				
			||||||
 | 
					      // TODO: pass full invoice
 | 
				
			||||||
      if (msg.includes('invoice expired')) throw new InvoiceExpiredError(hash)
 | 
					      if (msg.includes('invoice expired')) throw new InvoiceExpiredError(hash)
 | 
				
			||||||
      if (msg.includes('canceled')) throw new InvoiceCanceledError(hash)
 | 
					      if (msg.includes('canceled')) throw new InvoiceCanceledError(hash)
 | 
				
			||||||
      throw err
 | 
					      throw err
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user