re-use the same kyc function from withdrawal for deposits
This commit is contained in:
parent
eeea3e62a0
commit
2c14a180c1
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user