taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 51067e986316810dc577db8613896d81ca2a7a5a
parent 9c8904a2a56c121e383d3432f6f76668b445083e
Author: Florian Dold <florian@dold.me>
Date:   Tue, 27 May 2025 21:42:58 +0200

wallet-core: fix deposit auth transfer info

Diffstat:
Mpackages/taler-wallet-core/src/deposits.ts | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
1 file changed, 67 insertions(+), 29 deletions(-)

diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts @@ -92,6 +92,7 @@ import { cancelableFetch, cancelableLongPoll, constructTaskIdentifier, + genericWaitForState, runWithClientCancellation, spendCoins, } from "./common.js"; @@ -213,8 +214,22 @@ export class DepositTransactionContext implements TransactionContext { } let kycAuthTransferInfo: KycAuthTransferInfo | undefined = undefined; + let kycUrl: string | undefined; switch (dg.operationStatus) { + case DepositOperationStatus.PendingAggregateKyc: + case DepositOperationStatus.SuspendedAggregateKyc: + case DepositOperationStatus.PendingDepositKyc: + case DepositOperationStatus.SuspendedDepositKyc: { + if (!dg.kycInfo) { + break; + } + kycUrl = new URL( + `kyc-spa/${dg.kycInfo.accessToken}`, + dg.kycInfo.exchangeBaseUrl, + ).href; + break; + } case DepositOperationStatus.PendingDepositKycAuth: case DepositOperationStatus.SuspendedDepositKycAuth: { if (!dg.kycInfo) { @@ -239,7 +254,7 @@ export class DepositTransactionContext implements TransactionContext { accountPub: dg.merchantPub, creditPaytoUris: augmentPaytoUrisForKycTransfer( plainCreditPaytoUris, - dg.kycInfo?.paytoHash, + dg.merchantPub, // FIXME: Query tiny amount from exchange. `${dg.currency}:0.01`, ), @@ -278,12 +293,7 @@ export class DepositTransactionContext implements TransactionContext { kycAuthTransferInfo, kycPaytoHash: dg.kycInfo?.paytoHash, kycAccessToken: dg.kycInfo?.accessToken, - kycUrl: dg.kycInfo - ? new URL( - `kyc-spa/${dg.kycInfo.accessToken}`, - dg.kycInfo.exchangeBaseUrl, - ).href - : undefined, + kycUrl, ...(ort?.lastError ? { error: ort.lastError } : {}), }; } @@ -944,42 +954,70 @@ async function waitForRefreshOnDepositGroup( const abortRefreshGroupId = depositGroup.abortRefreshGroupId; checkLogicInvariant(!!abortRefreshGroupId); const ctx = new DepositTransactionContext(wex, depositGroup.depositGroupId); + + // Wait for the refresh transaction to be in a final state. + await genericWaitForState(wex, { + async checkState() { + return await wex.db.runReadWriteTx( + { storeNames: ["depositGroups", "refreshGroups", "transactionsMeta"] }, + async (tx) => { + const refreshGroup = await tx.refreshGroups.get(abortRefreshGroupId); + switch (refreshGroup?.operationStatus) { + case undefined: + case RefreshOperationStatus.Failed: + case RefreshOperationStatus.Finished: + return true; + } + return false; + }, + ); + }, + filterNotification(notif) { + return ( + notif.type === NotificationType.TransactionStateTransition && + notif.transactionId === abortRefreshGroupId + ); + }, + }); + const transitionInfo = await wex.db.runReadWriteTx( { storeNames: ["depositGroups", "refreshGroups", "transactionsMeta"] }, async (tx) => { const refreshGroup = await tx.refreshGroups.get(abortRefreshGroupId); let newOpState: DepositOperationStatus | undefined; - if (!refreshGroup) { - // Maybe it got manually deleted? Means that we should - // just go into aborted. - logger.warn("no aborting refresh group found for deposit group"); - newOpState = DepositOperationStatus.AbortedDeposit; - } else { - if (refreshGroup.operationStatus === RefreshOperationStatus.Finished) { + switch (refreshGroup?.operationStatus) { + case undefined: { + // Maybe it got manually deleted? Means that we should + // just go into aborted. + logger.warn("no aborting refresh group found for deposit group"); newOpState = DepositOperationStatus.AbortedDeposit; - } else if ( - refreshGroup.operationStatus === RefreshOperationStatus.Failed - ) { + break; + } + case RefreshOperationStatus.Failed: + case RefreshOperationStatus.Finished: { newOpState = DepositOperationStatus.AbortedDeposit; + break; } + default: + return undefined; } - if (newOpState) { - const newDg = await tx.depositGroups.get(depositGroup.depositGroupId); - if (!newDg) { - return; - } - const oldTxState = computeDepositTransactionStatus(newDg); - newDg.operationStatus = newOpState; - const newTxState = computeDepositTransactionStatus(newDg); - await tx.depositGroups.put(newDg); - await ctx.updateTransactionMeta(tx); - return { oldTxState, newTxState, balanceEffect: BalanceEffect.Any }; + const newDg = await tx.depositGroups.get(depositGroup.depositGroupId); + if (!newDg) { + return; } - return undefined; + const oldTxState = computeDepositTransactionStatus(newDg); + newDg.operationStatus = newOpState; + const newTxState = computeDepositTransactionStatus(newDg); + await tx.depositGroups.put(newDg); + await ctx.updateTransactionMeta(tx); + return { oldTxState, newTxState, balanceEffect: BalanceEffect.Any }; }, ); notifyTransition(wex, ctx.transactionId, transitionInfo); + if (transitionInfo) { + return TaskRunResult.progress(); + } return TaskRunResult.backoff(); }