aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/taler-wallet-core/src/db.ts5
-rw-r--r--packages/taler-wallet-core/src/operations/deposits.ts40
-rw-r--r--packages/taler-wallet-core/src/operations/withdraw.ts82
3 files changed, 77 insertions, 50 deletions
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
index e6131334c..d2d01e100 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -1361,7 +1361,8 @@ export type WgInfo =
| WgInfoBankPeerPush
| WgInfoBankRecoup;
-export interface WithdrawalKycPendingInfo {
+export type KycUserType = "individual" | "business";
+export interface KycPendingInfo {
paytoHash: string;
requirementRow: number;
}
@@ -1380,7 +1381,7 @@ export interface WithdrawalGroupRecord {
wgInfo: WgInfo;
- kycPending?: WithdrawalKycPendingInfo;
+ kycPending?: KycPendingInfo;
/**
* Secret seed used to derive planchets.
diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts
index b529e5ead..71caae5b3 100644
--- a/packages/taler-wallet-core/src/operations/deposits.ts
+++ b/packages/taler-wallet-core/src/operations/deposits.ts
@@ -21,6 +21,7 @@ import {
AbsoluteTime,
AmountJson,
Amounts,
+ bytesToString,
CancellationToken,
canonicalJson,
codecForDepositSuccess,
@@ -35,6 +36,7 @@ import {
ExchangeDepositRequest,
GetFeeForDepositRequest,
getRandomBytes,
+ hashTruncate32,
hashWire,
HttpStatusCode,
Logger,
@@ -44,6 +46,7 @@ import {
PrepareDepositRequest,
PrepareDepositResponse,
RefreshReason,
+ stringToBytes,
TalerErrorCode,
TalerProtocolTimestamp,
TrackDepositGroupRequest,
@@ -59,6 +62,7 @@ import {
TransactionStatus,
} from "../db.js";
import { TalerError } from "../errors.js";
+import { checkKycStatus } from "../index.js";
import { InternalWalletState } from "../internal-wallet-state.js";
import { readSuccessResponseJsonOrThrow } from "../util/http.js";
import { OperationAttemptResult } from "../util/retries.js";
@@ -151,7 +155,28 @@ export async function processDepositGroup(
if (depositGroup.transactionPerCoin[i] !== TransactionStatus.Wired) {
const track = await trackDepositPermission(ws, depositGroup, perm);
- updatedTxStatus = txStatusFromTrack(track);
+
+ if (track.type === "accepted") {
+ if (!track.kyc_ok && track.requirement_row !== undefined) {
+ updatedTxStatus = TransactionStatus.KycRequired;
+ const { requirement_row: requirementRow } = track;
+ const paytoHash = encodeCrock(
+ hashTruncate32(stringToBytes(depositGroup.wire.payto_uri + "\0")),
+ );
+ await checkKycStatus(
+ ws,
+ perm.exchange_url,
+ { paytoHash, requirementRow },
+ "individual",
+ );
+ } else {
+ updatedTxStatus = TransactionStatus.Accepted;
+ }
+ } else if (track.type === "wired") {
+ updatedTxStatus = TransactionStatus.Wired;
+ } else {
+ updatedTxStatus = TransactionStatus.Unknown;
+ }
}
if (updatedTxStatus !== undefined || updatedDeposit !== undefined) {
@@ -199,19 +224,6 @@ export async function processDepositGroup(
return OperationAttemptResult.finishedEmpty();
}
-function txStatusFromTrack(t: TrackTransaction): TransactionStatus {
- if (t.type === "accepted") {
- if (!t.kyc_ok && t.requirement_row !== undefined) {
- return TransactionStatus.KycRequired;
- }
- return TransactionStatus.Accepted;
- }
- if (t.type === "wired") {
- return TransactionStatus.Wired;
- }
- return TransactionStatus.Unknown;
-}
-
export async function trackDepositGroup(
ws: InternalWalletState,
req: TrackDepositGroupRequest,
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts
index a1a39bf32..c1cc94413 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -26,7 +26,6 @@ import {
AmountJson,
AmountLike,
Amounts,
- AmountString,
BankWithdrawDetails,
CancellationToken,
canonicalizeBaseUrl,
@@ -70,13 +69,14 @@ import {
CoinSourceType,
DenominationRecord,
DenominationVerificationStatus,
+ KycPendingInfo,
+ KycUserType,
PlanchetRecord,
PlanchetStatus,
WalletStoresV1,
WgInfo,
WithdrawalGroupRecord,
WithdrawalGroupStatus,
- WithdrawalKycPendingInfo,
WithdrawalRecordType,
} from "../db.js";
import {
@@ -86,7 +86,6 @@ import {
} from "../errors.js";
import { InternalWalletState } from "../internal-wallet-state.js";
import {
- getExchangeTosStatus,
makeCoinAvailable,
makeExchangeListItem,
runOperationWithErrorReporting,
@@ -927,7 +926,7 @@ async function queryReserve(
);
reserveUrl.searchParams.set("timeout_ms", "30000");
- logger.info(`querying reserve status via ${reserveUrl}`);
+ logger.info(`querying reserve status via ${reserveUrl.href}`);
const resp = await ws.http.get(reserveUrl.href, {
timeout: getReserveRequestTimeout(withdrawalGroup),
@@ -1165,9 +1164,9 @@ export async function processWithdrawalGroup(
let numFinished = 0;
let numKycRequired = 0;
let finishedForFirstTime = false;
- let errorsPerCoin: Record<number, TalerErrorDetail> = {};
+ const errorsPerCoin: Record<number, TalerErrorDetail> = {};
- let res = await ws.db
+ const res = await ws.db
.mktx((x) => [x.coins, x.withdrawalGroups, x.planchets])
.runReadWrite(async (tx) => {
const wg = await tx.withdrawalGroups.get(withdrawalGroupId);
@@ -1210,39 +1209,22 @@ export async function processWithdrawalGroup(
if (numKycRequired > 0) {
if (kycInfo) {
- const url = new URL(
- `kyc-check/${kycInfo.requirementRow}/${kycInfo.paytoHash}/individual`,
+ await checkKycStatus(
+ ws,
withdrawalGroup.exchangeBaseUrl,
+ kycInfo,
+ "individual",
);
- logger.info(`kyc url ${url.href}`);
- const kycStatusReq = await ws.http.fetch(url.href, {
- method: "GET",
- });
- logger.warn("kyc requested, but already fulfilled");
- if (kycStatusReq.status === HttpStatusCode.Ok) {
- return {
- type: OperationAttemptResultType.Pending,
- result: undefined,
- };
- } else if (kycStatusReq.status === HttpStatusCode.Accepted) {
- const kycStatus = await kycStatusReq.json();
- logger.info(`kyc status: ${j2s(kycStatus)}`);
- throw TalerError.fromDetail(
- TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED,
- {
- kycUrl: kycStatus.kyc_url,
- },
- `KYC check required for withdrawal`,
- );
- } else {
- throw Error(
- `unexpected response from kyc-check (${kycStatusReq.status})`,
- );
- }
+ return {
+ type: OperationAttemptResultType.Pending,
+ result: undefined,
+ };
} else {
throw TalerError.fromDetail(
TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED,
- {},
+ {
+ //FIXME we can't rise KYC error here since we don't have the url
+ } as any,
`KYC check required for withdrawal (not yet implemented in wallet-core)`,
);
}
@@ -1270,6 +1252,38 @@ export async function processWithdrawalGroup(
};
}
+export async function checkKycStatus(
+ ws: InternalWalletState,
+ exchangeUrl: string,
+ kycInfo: KycPendingInfo,
+ userType: KycUserType,
+): Promise<void> {
+ const url = new URL(
+ `kyc-check/${kycInfo.requirementRow}/${kycInfo.paytoHash}/${userType}`,
+ exchangeUrl,
+ );
+ logger.info(`kyc url ${url.href}`);
+ const kycStatusReq = await ws.http.fetch(url.href, {
+ method: "GET",
+ });
+ logger.warn("kyc requested, but already fulfilled");
+ if (kycStatusReq.status === HttpStatusCode.Ok) {
+ return;
+ } else if (kycStatusReq.status === HttpStatusCode.Accepted) {
+ const kycStatus = await kycStatusReq.json();
+ logger.info(`kyc status: ${j2s(kycStatus)}`);
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED,
+ {
+ kycUrl: kycStatus.kyc_url,
+ },
+ `KYC check required for withdrawal`,
+ );
+ } else {
+ throw Error(`unexpected response from kyc-check (${kycStatusReq.status})`);
+ }
+}
+
const AGE_MASK_GROUPS = "8:10:12:14:16:18"
.split(":")
.map((n) => parseInt(n, 10));