export const promoteTransaction = (bundleHash, accountName, powFn) => (dispatch, getState) => { dispatch(promoteTransactionRequest(bundleHash)); const remotePoW = getRemotePoWFromState(getState()); if (!remotePoW) { dispatch( generateAlert( 'info', i18next.t('global:promotingTransaction'), i18next.t('global:deviceMayBecomeUnresponsive'), ), ); } let accountState = {}; try { accountState = await syncAccount()(selectedAccountStateFactory(accountName)(getState())); dispatch(syncAccountBeforeManualPromotion(accountState)); const transaction = accountState.transfers[bundleHash]; if (transaction.persistence) { throw new Error(Errors.TRANSACTION_ALREADY_CONFIRMED); } let isValid = await isStillAValidTransaction()(transaction, accountState.addresses); if (!isValid) { throw new Error(Errors.BUNDLE_NO_LONGER_VALID); } const tailTransactions = accountState.transfers[bundleHash].tailTransactions; let consistentTail = await findPromotableTail()(tailTransactions, 0); let hash = await dispatch( forceTransactionPromotion( accountName, consistentTail, accountState.transfers[bundleHash].tailTransactions, true, // If proof of work configuration is set to remote, pass proof of work function as null remotePoW ? null : powFn, ), ); dispatch( generateAlert( 'success', i18next.t('global:promoted'), i18next.t('global:promotedExplanation', { hash }), ), ); return dispatch(promoteTransactionSuccess()); } catch(err) { if (err.message === Errors.BUNDLE_NO_LONGER_VALID) { dispatch(generateAlert('error', i18next.t('global:promotionError'), i18next.t('global:noLongerValid'))); } else if (err.message.includes(Errors.ATTACH_TO_TANGLE_UNAVAILABLE)) { dispatch( generateAlert( 'error', i18next.t('global:attachToTangleUnavailable'), i18next.t('global:attachToTangleUnavailableExplanationShort'), 10000, ), ); } else if (err.message === Errors.TRANSACTION_ALREADY_CONFIRMED) { dispatch( generateAlert( 'success', i18next.t('global:transactionAlreadyConfirmed'), i18next.t('global:transactionAlreadyConfirmedExplanation'), ), ); } else { dispatch(generatePromotionErrorAlert(err)); } return dispatch(promoteTransactionError()); } };