/* This file is part of GNU Taler (C) 2022-2024 Taler Systems S.A. GNU Taler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see */ import { Attention, Button, convertUiField, FormMetadata, getConverterById, LocalNotificationBanner, RenderAllFieldsByUiConfig, UIHandlerId, useExchangeApiContext, useLocalNotificationHandler, useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { FormErrors, getRequiredFields, getShapeFromFields, useFormState, validateRequiredFields, } from "../hooks/form.js"; import { undefinedIfEmpty } from "./Start.js"; import { AbsoluteTime, AccessToken, AmountJson, Amounts, AmountString, assertUnreachable, createNewOfficerAccount, createNewWalletKycAccount, HttpStatusCode, } from "@gnu-taler/taler-util"; import { useEffect, useMemo, useState } from "preact/hooks"; type FormType = { amount: AmountJson; }; type Props = { onKycStarted: (token: AccessToken) => void; }; export function TriggerKyc({ onKycStarted }: Props): VNode { const { i18n } = useTranslationContext(); const [notification, withErrorHandler, notify] = useLocalNotificationHandler(); const { config, lib } = useExchangeApiContext(); const [kycAccount, setKycAccount] = useState(); const theForm: FormMetadata = { id: "asd", version: 1, label: i18n.str`Trigger KYC balance`, config: { type: "double-column", design: [ { title: i18n.str`Trigger KYC Balance`, fields: [ { id: ".amount" as UIHandlerId, type: "amount", currency: config.currency, label: i18n.str`Amount`, required: true, converterId: "Taler.Amount", }, ], }, ], }, }; const shape: Array = []; const requiredFields: Array = []; theForm.config.design.forEach((section) => { Array.prototype.push.apply(shape, getShapeFromFields(section.fields)); Array.prototype.push.apply( requiredFields, getRequiredFields(section.fields), ); }); const [form, state] = useFormState( shape, { amount: Amounts.parseOrThrow(`${config.currency}:1000000`), }, (st) => { const partialErrors = undefinedIfEmpty>({}); const errors = undefinedIfEmpty | undefined>( validateRequiredFields(partialErrors, st, requiredFields), ); if (errors === undefined) { return { status: "ok", result: st as any, errors: undefined, }; } return { status: "fail", result: st as any, errors, }; }, ); const accountPromise = useMemo(async () => { const resp = await lib.exchange.getSeed(); const extraEntropy = resp.type === "ok" ? resp.body : new Uint8Array(); return createNewWalletKycAccount(extraEntropy); }, [1]); useEffect(() => { if (!kycAccount) return; const paytoHash = kycAccount async function check() { const {signingKey} = await accountPromise; const result = await lib.exchange.checkKycStatus(signingKey, paytoHash); if (result.type === "ok") { if (result.body) { onKycStarted(result.body.access_token) } else { console.log("empty body") } } else { switch(result.case) { case HttpStatusCode.Forbidden:{ notify({ type: "error", title: i18n.str`could not create token`, description: i18n.str`access denied`, when: AbsoluteTime.now(), }) } case HttpStatusCode.NotFound: { notify({ type: "error", title: i18n.str`could not create token`, description: i18n.str`not found`, when: AbsoluteTime.now(), }) } case HttpStatusCode.Conflict: { notify({ type: "error", title: i18n.str`could not create token`, description: i18n.str`conflict`, when: AbsoluteTime.now(), }) } } } } check() }, [kycAccount]); const submitHandler = theForm === undefined || state.status === "fail" ? undefined : withErrorHandler( async () => { const account = await accountPromise; return lib.exchange.notifyKycBalanceLimit( account, Amounts.stringify(state.result.amount), ); }, (res) => { notify({ type: "info", title: i18n.str`No kyc required`, when: AbsoluteTime.now(), }); }, (fail) => { switch (fail.case) { case HttpStatusCode.Forbidden: return i18n.str`Access denied trying to test balance.`; case HttpStatusCode.UnavailableForLegalReasons: setKycAccount(fail.body.h_payto); return i18n.str`Unavailable For Legal Reasons`; default: assertUnreachable(fail); } }, ); if (kycAccount) { return
loading...
} return (
{theForm.config.design.map((section, i) => { if (!section) return ; return (

{section.title}

{section.description && (

{section.description}

)}
); })}
); }