diff options
Diffstat (limited to 'packages/taler-wallet-core/src/operations/withdraw.ts')
-rw-r--r-- | packages/taler-wallet-core/src/operations/withdraw.ts | 134 |
1 files changed, 64 insertions, 70 deletions
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index d1816de03..d0c4d453f 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -135,6 +135,7 @@ import { notifyTransition, stopLongpolling, } from "./transactions.js"; +import { assertUnreachable } from "../util/assertUnreachable.js"; /** * Logger for this file. @@ -160,25 +161,25 @@ export async function suspendWithdrawalTransaction( } let newStatus: WithdrawalGroupStatus | undefined = undefined; switch (wg.status) { - case WithdrawalGroupStatus.Ready: + case WithdrawalGroupStatus.PendingReady: newStatus = WithdrawalGroupStatus.SuspendedReady; break; case WithdrawalGroupStatus.AbortingBank: newStatus = WithdrawalGroupStatus.SuspendedAbortingBank; break; - case WithdrawalGroupStatus.WaitConfirmBank: + case WithdrawalGroupStatus.PendingWaitConfirmBank: newStatus = WithdrawalGroupStatus.SuspendedWaitConfirmBank; break; - case WithdrawalGroupStatus.RegisteringBank: + case WithdrawalGroupStatus.PendingRegisteringBank: newStatus = WithdrawalGroupStatus.SuspendedRegisteringBank; break; - case WithdrawalGroupStatus.QueryingStatus: - newStatus = WithdrawalGroupStatus.QueryingStatus; + case WithdrawalGroupStatus.PendingQueryingStatus: + newStatus = WithdrawalGroupStatus.SuspendedQueryingStatus; break; - case WithdrawalGroupStatus.Kyc: + case WithdrawalGroupStatus.PendingKyc: newStatus = WithdrawalGroupStatus.SuspendedKyc; break; - case WithdrawalGroupStatus.Aml: + case WithdrawalGroupStatus.PendingAml: newStatus = WithdrawalGroupStatus.SuspendedAml; break; default: @@ -221,25 +222,25 @@ export async function resumeWithdrawalTransaction( let newStatus: WithdrawalGroupStatus | undefined = undefined; switch (wg.status) { case WithdrawalGroupStatus.SuspendedReady: - newStatus = WithdrawalGroupStatus.Ready; + newStatus = WithdrawalGroupStatus.PendingReady; break; case WithdrawalGroupStatus.SuspendedAbortingBank: newStatus = WithdrawalGroupStatus.AbortingBank; break; case WithdrawalGroupStatus.SuspendedWaitConfirmBank: - newStatus = WithdrawalGroupStatus.WaitConfirmBank; + newStatus = WithdrawalGroupStatus.PendingWaitConfirmBank; break; case WithdrawalGroupStatus.SuspendedQueryingStatus: - newStatus = WithdrawalGroupStatus.QueryingStatus; + newStatus = WithdrawalGroupStatus.PendingQueryingStatus; break; case WithdrawalGroupStatus.SuspendedRegisteringBank: - newStatus = WithdrawalGroupStatus.RegisteringBank; + newStatus = WithdrawalGroupStatus.PendingRegisteringBank; break; case WithdrawalGroupStatus.SuspendedAml: - newStatus = WithdrawalGroupStatus.Aml; + newStatus = WithdrawalGroupStatus.PendingAml; break; case WithdrawalGroupStatus.SuspendedKyc: - newStatus = WithdrawalGroupStatus.Kyc; + newStatus = WithdrawalGroupStatus.PendingKyc; break; default: logger.warn( @@ -289,21 +290,21 @@ export async function abortWithdrawalTransaction( } let newStatus: WithdrawalGroupStatus | undefined = undefined; switch (wg.status) { - case WithdrawalGroupStatus.WaitConfirmBank: - case WithdrawalGroupStatus.RegisteringBank: + case WithdrawalGroupStatus.PendingWaitConfirmBank: + case WithdrawalGroupStatus.PendingRegisteringBank: case WithdrawalGroupStatus.AbortingBank: newStatus = WithdrawalGroupStatus.AbortingBank; break; - case WithdrawalGroupStatus.Aml: + case WithdrawalGroupStatus.PendingAml: newStatus = WithdrawalGroupStatus.SuspendedAml; break; - case WithdrawalGroupStatus.Kyc: + case WithdrawalGroupStatus.PendingKyc: newStatus = WithdrawalGroupStatus.SuspendedKyc; break; - case WithdrawalGroupStatus.QueryingStatus: + case WithdrawalGroupStatus.PendingQueryingStatus: newStatus = WithdrawalGroupStatus.SuspendedQueryingStatus; break; - case WithdrawalGroupStatus.Ready: + case WithdrawalGroupStatus.PendingReady: newStatus = WithdrawalGroupStatus.SuspendedReady; break; case WithdrawalGroupStatus.SuspendedAbortingBank: @@ -316,9 +317,13 @@ export async function abortWithdrawalTransaction( case WithdrawalGroupStatus.SuspendedRegisteringBank: case WithdrawalGroupStatus.SuspendedWaitConfirmBank: case WithdrawalGroupStatus.Finished: - case WithdrawalGroupStatus.BankAborted: + case WithdrawalGroupStatus.FailedBankAborted: + case WithdrawalGroupStatus.AbortedExchange: + case WithdrawalGroupStatus.FailedAbortingBank: // Not allowed break; + default: + assertUnreachable(wg.status); } if (newStatus != null) { const oldTxState = computeWithdrawalTransactionStatus(wg); @@ -385,7 +390,7 @@ export function computeWithdrawalTransactionStatus( wgRecord: WithdrawalGroupRecord, ): TransactionState { switch (wgRecord.status) { - case WithdrawalGroupStatus.BankAborted: + case WithdrawalGroupStatus.FailedBankAborted: return { major: TransactionMajorState.Aborted, }; @@ -393,22 +398,22 @@ export function computeWithdrawalTransactionStatus( return { major: TransactionMajorState.Done, }; - case WithdrawalGroupStatus.RegisteringBank: + case WithdrawalGroupStatus.PendingRegisteringBank: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.BankRegisterReserve, }; - case WithdrawalGroupStatus.Ready: + case WithdrawalGroupStatus.PendingReady: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.WithdrawCoins, }; - case WithdrawalGroupStatus.QueryingStatus: + case WithdrawalGroupStatus.PendingQueryingStatus: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.ExchangeWaitReserve, }; - case WithdrawalGroupStatus.WaitConfirmBank: + case WithdrawalGroupStatus.PendingWaitConfirmBank: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.BankConfirmTransfer, @@ -444,13 +449,13 @@ export function computeWithdrawalTransactionStatus( minor: TransactionMinorState.WithdrawCoins, }; } - case WithdrawalGroupStatus.Aml: { + case WithdrawalGroupStatus.PendingAml: { return { major: TransactionMajorState.Pending, minor: TransactionMinorState.AmlRequired, }; } - case WithdrawalGroupStatus.Kyc: { + case WithdrawalGroupStatus.PendingKyc: { return { major: TransactionMajorState.Pending, minor: TransactionMinorState.KycRequired, @@ -473,6 +478,11 @@ export function computeWithdrawalTransactionStatus( major: TransactionMajorState.Failed, minor: TransactionMinorState.AbortingBank, }; + case WithdrawalGroupStatus.AbortedExchange: + return { + major: TransactionMajorState.Aborted, + minor: TransactionMinorState.Exchange, + } } } @@ -1122,7 +1132,7 @@ async function queryReserve( withdrawalGroupId, }); checkDbInvariant(!!withdrawalGroup); - if (withdrawalGroup.status !== WithdrawalGroupStatus.QueryingStatus) { + if (withdrawalGroup.status !== WithdrawalGroupStatus.PendingQueryingStatus) { return { ready: true }; } const reservePub = withdrawalGroup.reservePub; @@ -1135,7 +1145,7 @@ async function queryReserve( logger.info(`querying reserve status via ${reserveUrl.href}`); - const resp = await ws.http.get(reserveUrl.href, { + const resp = await ws.http.fetch(reserveUrl.href, { timeout: getReserveRequestTimeout(withdrawalGroup), cancellationToken, }); @@ -1177,7 +1187,7 @@ async function queryReserve( return undefined; } const txStateOld = computeWithdrawalTransactionStatus(wg); - wg.status = WithdrawalGroupStatus.Ready; + wg.status = WithdrawalGroupStatus.PendingReady; const txStateNew = computeWithdrawalTransactionStatus(wg); wg.reserveBalanceAmount = Amounts.stringify(result.response.balance); await tx.withdrawalGroups.put(wg); @@ -1250,12 +1260,12 @@ export async function processWithdrawalGroup( } switch (withdrawalGroup.status) { - case WithdrawalGroupStatus.RegisteringBank: + case WithdrawalGroupStatus.PendingRegisteringBank: await processReserveBankStatus(ws, withdrawalGroupId); return await processWithdrawalGroup(ws, withdrawalGroupId, { forceNow: true, }); - case WithdrawalGroupStatus.QueryingStatus: { + case WithdrawalGroupStatus.PendingQueryingStatus: { runLongpollAsync(ws, retryTag, (ct) => { return queryReserve(ws, withdrawalGroupId, ct); }); @@ -1266,7 +1276,7 @@ export async function processWithdrawalGroup( type: OperationAttemptResultType.Longpoll, }; } - case WithdrawalGroupStatus.WaitConfirmBank: { + case WithdrawalGroupStatus.PendingWaitConfirmBank: { const res = await processReserveBankStatus(ws, withdrawalGroupId); switch (res.status) { case BankStatusResultCode.Aborted: @@ -1284,7 +1294,7 @@ export async function processWithdrawalGroup( } break; } - case WithdrawalGroupStatus.BankAborted: { + case WithdrawalGroupStatus.FailedBankAborted: { // FIXME return { type: OperationAttemptResultType.Pending, @@ -1294,7 +1304,7 @@ export async function processWithdrawalGroup( case WithdrawalGroupStatus.Finished: // We can try to withdraw, nothing needs to be done with the reserve. break; - case WithdrawalGroupStatus.Ready: + case WithdrawalGroupStatus.PendingReady: // Continue with the actual withdrawal! break; default: @@ -1847,8 +1857,8 @@ async function registerReserveWithBank( withdrawalGroupId, }); switch (withdrawalGroup?.status) { - case WithdrawalGroupStatus.WaitConfirmBank: - case WithdrawalGroupStatus.RegisteringBank: + case WithdrawalGroupStatus.PendingWaitConfirmBank: + case WithdrawalGroupStatus.PendingRegisteringBank: break; default: return; @@ -1885,8 +1895,8 @@ async function registerReserveWithBank( return undefined; } switch (r.status) { - case WithdrawalGroupStatus.RegisteringBank: - case WithdrawalGroupStatus.WaitConfirmBank: + case WithdrawalGroupStatus.PendingRegisteringBank: + case WithdrawalGroupStatus.PendingWaitConfirmBank: break; default: return; @@ -1898,7 +1908,7 @@ async function registerReserveWithBank( AbsoluteTime.now(), ); const oldTxState = computeWithdrawalTransactionStatus(r); - r.status = WithdrawalGroupStatus.WaitConfirmBank; + r.status = WithdrawalGroupStatus.PendingWaitConfirmBank; const newTxState = computeWithdrawalTransactionStatus(r); await tx.withdrawalGroups.put(r); return { @@ -1928,8 +1938,8 @@ async function processReserveBankStatus( withdrawalGroupId, }); switch (withdrawalGroup?.status) { - case WithdrawalGroupStatus.WaitConfirmBank: - case WithdrawalGroupStatus.RegisteringBank: + case WithdrawalGroupStatus.PendingWaitConfirmBank: + case WithdrawalGroupStatus.PendingRegisteringBank: break; default: return { @@ -1969,8 +1979,8 @@ async function processReserveBankStatus( return; } switch (r.status) { - case WithdrawalGroupStatus.RegisteringBank: - case WithdrawalGroupStatus.WaitConfirmBank: + case WithdrawalGroupStatus.PendingRegisteringBank: + case WithdrawalGroupStatus.PendingWaitConfirmBank: break; default: return; @@ -1981,7 +1991,7 @@ async function processReserveBankStatus( const now = AbsoluteTime.toTimestamp(AbsoluteTime.now()); const oldTxState = computeWithdrawalTransactionStatus(r); r.wgInfo.bankInfo.timestampBankConfirmed = now; - r.status = WithdrawalGroupStatus.BankAborted; + r.status = WithdrawalGroupStatus.FailedBankAborted; const newTxState = computeWithdrawalTransactionStatus(r); await tx.withdrawalGroups.put(r); return { @@ -2002,7 +2012,7 @@ async function processReserveBankStatus( } // FIXME: Why do we do this?! - if (withdrawalGroup.status === WithdrawalGroupStatus.RegisteringBank) { + if (withdrawalGroup.status === WithdrawalGroupStatus.PendingRegisteringBank) { await registerReserveWithBank(ws, withdrawalGroupId); return await processReserveBankStatus(ws, withdrawalGroupId); } @@ -2016,8 +2026,8 @@ async function processReserveBankStatus( } // Re-check reserve status within transaction switch (r.status) { - case WithdrawalGroupStatus.RegisteringBank: - case WithdrawalGroupStatus.WaitConfirmBank: + case WithdrawalGroupStatus.PendingRegisteringBank: + case WithdrawalGroupStatus.PendingWaitConfirmBank: break; default: return undefined; @@ -2030,7 +2040,7 @@ async function processReserveBankStatus( logger.info("withdrawal: transfer confirmed by bank."); const now = AbsoluteTime.toTimestamp(AbsoluteTime.now()); r.wgInfo.bankInfo.timestampBankConfirmed = now; - r.status = WithdrawalGroupStatus.QueryingStatus; + r.status = WithdrawalGroupStatus.PendingQueryingStatus; // FIXME: Notification is deprecated with DD37. ws.notify({ type: NotificationType.WithdrawalGroupBankConfirmed, @@ -2276,7 +2286,7 @@ export async function acceptWithdrawalFromUri( }, restrictAge: req.restrictAge, forcedDenomSel: req.forcedDenomSel, - reserveStatus: WithdrawalGroupStatus.RegisteringBank, + reserveStatus: WithdrawalGroupStatus.PendingRegisteringBank, }); const withdrawalGroupId = withdrawalGroup.withdrawalGroupId; @@ -2291,19 +2301,14 @@ export async function acceptWithdrawalFromUri( const processedWithdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, { withdrawalGroupId, }); - if (processedWithdrawalGroup?.status === WithdrawalGroupStatus.BankAborted) { + if (processedWithdrawalGroup?.status === WithdrawalGroupStatus.FailedBankAborted) { throw TalerError.fromDetail( TalerErrorCode.WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK, {}, ); } - // Start withdrawal in the background - processWithdrawalGroup(ws, withdrawalGroupId, { - forceNow: true, - }).catch((err) => { - logger.error("Processing withdrawal (after creation) failed:", err); - }); + ws.workAvailable.trigger(); return { reservePub: withdrawalGroup.reservePub, @@ -2337,7 +2342,7 @@ export async function createManualWithdrawal( exchangeBaseUrl: req.exchangeBaseUrl, forcedDenomSel: req.forcedDenomSel, restrictAge: req.restrictAge, - reserveStatus: WithdrawalGroupStatus.QueryingStatus, + reserveStatus: WithdrawalGroupStatus.PendingQueryingStatus, }); const withdrawalGroupId = withdrawalGroup.withdrawalGroupId; @@ -2357,18 +2362,7 @@ export async function createManualWithdrawal( return await getFundingPaytoUris(tx, withdrawalGroup.withdrawalGroupId); }); - // Start withdrawal in the background (do not await!) - // FIXME: We could also interrupt the task look if it is waiting and - // rely on retry handling to re-process the withdrawal group. - runOperationWithErrorReporting( - ws, - TaskIdentifiers.forWithdrawal(withdrawalGroup), - async () => { - return await processWithdrawalGroup(ws, withdrawalGroupId, { - forceNow: true, - }); - }, - ); + ws.workAvailable.trigger(); return { reservePub: withdrawalGroup.reservePub, |