commit a6524293f1fd25704b876048f7b564000d76b6e3
parent 54ead87bbea0d1c8a8ba49ab9f3e345161153de0
Author: Florian Dold <florian@dold.me>
Date: Tue, 8 Jul 2025 21:28:40 +0200
wallet-core: unify deposit kyc and deposit kyc auth handling
Diffstat:
1 file changed, 18 insertions(+), 100 deletions(-)
diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts
@@ -1108,6 +1108,10 @@ async function processDepositGroupPendingKyc(
kycInfo.lastDeny = algoRes.lastDeny;
kycInfo.lastRuleGen = algoRes.lastRuleGen;
+ const requiresAuth =
+ algoRes.lastCheckStatus === HttpStatusCode.Conflict ||
+ algoRes.lastCheckStatus === HttpStatusCode.Forbidden;
+
// Now store the result.
return await wex.db.runReadWriteTx(
@@ -1120,8 +1124,20 @@ async function processDepositGroupPendingKyc(
const oldTxState = computeDepositTransactionStatus(newDg);
switch (newDg.operationStatus) {
case DepositOperationStatus.PendingAggregateKyc:
+ if (requiresAuth) {
+ throw Error("kyc auth during aggregation not yet supported");
+ }
break;
case DepositOperationStatus.PendingDepositKyc:
+ if (requiresAuth) {
+ newDg.operationStatus =
+ DepositOperationStatus.PendingDepositKycAuth;
+ }
+ break;
+ case DepositOperationStatus.PendingDepositKycAuth:
+ if (!requiresAuth) {
+ newDg.operationStatus = DepositOperationStatus.PendingDepositKyc;
+ }
break;
default:
return TaskRunResult.backoff();
@@ -1140,103 +1156,6 @@ async function processDepositGroupPendingKyc(
);
}
-async function processDepositGroupPendingKycAuth(
- wex: WalletExecutionContext,
- depositGroup: DepositGroupRecord,
-): Promise<TaskRunResult> {
- const { depositGroupId } = depositGroup;
- const ctx = new DepositTransactionContext(wex, depositGroupId);
-
- const kycInfo = depositGroup.kycInfo;
-
- if (!kycInfo) {
- throw Error(
- "invalid DB state, in pending(kyc-auth), but no kycInfo present",
- );
- }
-
- const sigResp = await wex.cryptoApi.signWalletKycAuth({
- accountPriv: depositGroup.merchantPriv,
- accountPub: depositGroup.merchantPub,
- });
-
- const url = new URL(
- `kyc-check/${kycInfo.paytoHash}`,
- kycInfo.exchangeBaseUrl,
- );
-
- // lpt=1 => wait for the KYC auth transfer (access token available)
- url.searchParams.set("lpt", "1");
- logger.info(`kyc url ${url.href}`);
- const kycStatusRes = await cancelableLongPoll(wex, url, {
- headers: {
- ["Account-Owner-Signature"]: sigResp.sig,
- ["Account-Owner-Pub"]: depositGroup.merchantPub,
- },
- });
-
- logger.info(`merchant pub: ${depositGroup.merchantPub}`);
-
- logger.info(
- `kyc-check for auth longpoll result status: ${kycStatusRes.status}`,
- );
-
- switch (kycStatusRes.status) {
- case HttpStatusCode.Ok:
- return await transitionKycAuthSuccess(ctx);
- case HttpStatusCode.NoContent:
- return await transitionKycAuthSuccess(ctx);
- case HttpStatusCode.Accepted:
- return await transitionKycAuthSuccess(ctx);
- case HttpStatusCode.Conflict:
- case HttpStatusCode.Forbidden:
- // FIXME: Also check error code
- logger.info("kyc auth still pending");
- return TaskRunResult.longpollReturnedPending();
- default:
- throwUnexpectedRequestError(
- kycStatusRes,
- await readTalerErrorResponse(kycStatusRes),
- );
- }
-}
-
-async function transitionKycAuthSuccess(
- ctx: DepositTransactionContext,
-): Promise<TaskRunResult> {
- const didTransition = await ctx.wex.db.runReadWriteTx(
- { storeNames: ["depositGroups", "transactionsMeta"] },
- async (tx) => {
- const newDg = await tx.depositGroups.get(ctx.depositGroupId);
- if (!newDg) {
- return false;
- }
- const oldTxState = computeDepositTransactionStatus(newDg);
- switch (newDg.operationStatus) {
- case DepositOperationStatus.PendingDepositKycAuth:
- newDg.operationStatus = DepositOperationStatus.PendingDeposit;
- break;
- default:
- return false;
- }
- await tx.depositGroups.put(newDg);
- await ctx.updateTransactionMeta(tx);
- const newTxState = computeDepositTransactionStatus(newDg);
- applyNotifyTransition(tx.notify, ctx.transactionId, {
- oldTxState,
- newTxState,
- balanceEffect: BalanceEffect.None,
- });
- return true;
- },
- );
- if (didTransition) {
- return TaskRunResult.progress();
- } else {
- return TaskRunResult.backoff();
- }
-}
-
/**
* Finds the reserve key pair of the most recent withdrawal
* with the given exchange.
@@ -1540,7 +1459,7 @@ async function processDepositGroupTrack(
let allWired = true;
- const transitionInfo = await wex.db.runReadWriteTx(
+ await wex.db.runReadWriteTx(
{ storeNames: ["depositGroups", "transactionsMeta"] },
async (tx) => {
const dg = await tx.depositGroups.get(depositGroupId);
@@ -1892,13 +1811,12 @@ export async function processDepositGroup(
return processDepositGroupTrack(wex, depositGroup);
case DepositOperationStatus.PendingAggregateKyc:
case DepositOperationStatus.PendingDepositKyc:
+ case DepositOperationStatus.PendingDepositKycAuth:
return processDepositGroupPendingKyc(wex, depositGroup);
case DepositOperationStatus.PendingDeposit:
return processDepositGroupPendingDeposit(wex, depositGroup);
case DepositOperationStatus.Aborting:
return processDepositGroupAborting(wex, depositGroup);
- case DepositOperationStatus.PendingDepositKycAuth:
- return processDepositGroupPendingKycAuth(wex, depositGroup);
}
return TaskRunResult.finished();