diff --git a/locales/en.json b/locales/en.json index af8098fba..2aaf531ff 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1092,7 +1092,8 @@ "error.failureReasonTimeout": "There are more routes to try, but the payment timeout was exceeded.", "error.failureReasonNoRoute": "No route found", "error.failureReasonError": "A non-recoverable error has occured", - "error.failureReasonIncorrectPaymentDetails": "Payment details incorrect (unknown hash, invalid amt or invalid final cltv delta)", + "error.failureReasonIncorrectPaymentDetails": "Payment failed: Payment details incorrect (unknown payment hash, invalid amount or invalid final CLTV delta).", + "error.failureReasonIncorrectPaymentDetailsKeysend": "The receiving node might not accept keysend payments.", "error.failureReasonInsufficientBalance": "Insufficient local balance", "pos.views.Wallet.PosPane.noOrders": "No orders open at the moment. To send to ZEUS, mark order as 'Other Payment Type' with a note that includes 'Zeus', 'BTC', or 'Bitcoin'", "pos.views.Wallet.PosPane.noOrdersStandalone": "No orders open at the moment", diff --git a/stores/TransactionsStore.ts b/stores/TransactionsStore.ts index e9ad568f9..5072dafc0 100644 --- a/stores/TransactionsStore.ts +++ b/stores/TransactionsStore.ts @@ -563,6 +563,11 @@ export default class TransactionsStore { ? lnrpc.Payment.PaymentStatus[result.status] : result.status; + const isKeysend = + result?.htlcs?.[0]?.route?.hops?.[0]?.custom_records?.[ + keySendPreimageType + ]; + // TODO add message for in-flight transactions if ( (status !== 'complete' && @@ -583,8 +588,11 @@ export default class TransactionsStore { ) : result.payment_error ) - : errorToUserFriendly(result.failure_reason)) || - errorToUserFriendly(result.payment_error); + : errorToUserFriendly( + result.failure_reason, + true, + isKeysend ? ['Keysend'] : undefined + )) || errorToUserFriendly(result.payment_error); } // lndhub if (result.error) { diff --git a/utils/ErrorUtils.test.ts b/utils/ErrorUtils.test.ts index d0711c42f..f669454a7 100644 --- a/utils/ErrorUtils.test.ts +++ b/utils/ErrorUtils.test.ts @@ -1,5 +1,12 @@ import { errorToUserFriendly } from './ErrorUtils'; +jest.mock('./LocaleUtils', () => ({ + localeString: (key: string) => { + const EN = require('../locales/en.json'); + return EN[key]; + } +})); + describe('ErrorUtils', () => { describe('errorToUserFriendly', () => { it('Turns error message to user friendly values', () => { @@ -91,6 +98,36 @@ describe('ErrorUtils', () => { ); }); + it('Returns normal error message for unhandled errorContext', () => { + expect( + errorToUserFriendly( + Object.assign(new Error(), { + message: 'FAILURE_REASON_INCORRECT_PAYMENT_DETAILS', + name: 'test' + }), + true, + ['UnhandledContext'] + ) + ).toEqual( + 'Payment failed: Payment details incorrect (unknown payment hash, invalid amount or invalid final CLTV delta).' + ); + }); + + it('Handles Keysend errorContext with additional message', () => { + expect( + errorToUserFriendly( + Object.assign(new Error(), { + message: 'FAILURE_REASON_INCORRECT_PAYMENT_DETAILS', + name: 'test' + }), + true, + ['Keysend'] + ) + ).toEqual( + 'Payment failed: Payment details incorrect (unknown payment hash, invalid amount or invalid final CLTV delta). The receiving node might not accept keysend payments.' + ); + }); + it('Returns inputted error if no match found', () => { expect( errorToUserFriendly( diff --git a/utils/ErrorUtils.ts b/utils/ErrorUtils.ts index 1d688408c..a9982216f 100644 --- a/utils/ErrorUtils.ts +++ b/utils/ErrorUtils.ts @@ -17,7 +17,11 @@ const userFriendlyErrors: any = { const pascalCase = /^[A-Z](([a-z0-9]+[A-Z]?)*)$/; -const errorToUserFriendly = (error: Error, localize = true) => { +const errorToUserFriendly = ( + error: Error, + localize = true, + errorContext?: string[] +) => { let errorMessage: string = error?.message; let errorObject: any; @@ -46,12 +50,23 @@ const errorToUserFriendly = (error: Error, localize = true) => { if (localize) { const localeString = require('./LocaleUtils').localeString; - return ( + let baseError = localeString(userFriendlyErrors[errorMsg])?.replace( 'Zeus', 'ZEUS' - ) || errorMsg - ); + ) || errorMsg; + + if ( + errorContext?.includes('Keysend') && + errorMsg === 'FAILURE_REASON_INCORRECT_PAYMENT_DETAILS' + ) { + baseError += + ' ' + + localeString( + 'error.failureReasonIncorrectPaymentDetailsKeysend' + ); + } + return baseError; } else { const EN = require('../locales/en.json'); return EN[userFriendlyErrors[errorMsg]] || errorMsg;