summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts')
-rw-r--r--packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts171
1 files changed, 171 insertions, 0 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
new file mode 100644
index 000000000..99de03d2d
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
@@ -0,0 +1,171 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 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 <http://www.gnu.org/licenses/>
+ */
+
+import {
+ AbsoluteTime,
+ Amounts,
+ NotificationType,
+ PreparePayResult,
+ PreparePayResultType,
+ TalerProtocolTimestamp,
+} from "@gnu-taler/taler-util";
+import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import { useEffect } from "preact/hooks";
+import { alertFromError, useAlertContext } from "../../context/alert.js";
+import { useBackendContext } from "../../context/backend.js";
+import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
+import { Props, State } from "./index.js";
+
+export function useComponentState({
+ talerPayPullUri,
+ onClose,
+ goToWalletManualWithdraw,
+ onSuccess,
+}: Props): State {
+ const api = useBackendContext();
+ const { i18n } = useTranslationContext();
+ const { pushAlertOnError } = useAlertContext();
+ const hook = useAsyncAsHook(async () => {
+ const p2p = await api.wallet.call(WalletApiOperation.PreparePeerPullDebit, {
+ talerUri: talerPayPullUri,
+ });
+ const balance = await api.wallet.call(WalletApiOperation.GetBalances, {});
+ return { p2p, balance };
+ });
+
+ useEffect(() =>
+ api.listener.onUpdateNotification(
+ [NotificationType.TransactionStateTransition],
+ hook?.retry,
+ ),
+ );
+
+ if (!hook) {
+ return {
+ status: "loading",
+ error: undefined,
+ };
+ }
+ if (hook.hasError) {
+ return {
+ status: "error",
+ error: alertFromError(
+ i18n,
+ i18n.str`Could not load the transfer payment status`,
+ hook,
+ ),
+ };
+ }
+ // if (hook.hasError) {
+ // return {
+ // status: "loading-uri",
+ // error: hook,
+ // };
+ // }
+
+ const { contractTerms, transactionId, amountEffective, amountRaw } =
+ hook.response.p2p;
+
+ const amountStr: string = contractTerms.amount;
+ const amount = Amounts.parseOrThrow(amountStr);
+ const effective = Amounts.parseOrThrow(amountEffective);
+ const raw = Amounts.parseOrThrow(amountRaw);
+ const summary: string | undefined = contractTerms.summary;
+ const expiration: TalerProtocolTimestamp | undefined =
+ contractTerms.purse_expiration;
+
+ const foundBalance = hook.response.balance.balances.find(
+ (b) => Amounts.parseOrThrow(b.available).currency === amount.currency,
+ );
+
+ const paymentPossible: PreparePayResult = {
+ status: PreparePayResultType.PaymentPossible,
+ proposalId: "fakeID",
+ contractTerms: {} as any,
+ contractTermsHash: "asd",
+ amountRaw: hook.response.p2p.amount,
+ amountEffective: hook.response.p2p.amount,
+ } as PreparePayResult;
+
+ const insufficientBalance: PreparePayResult = {
+ status: PreparePayResultType.InsufficientBalance,
+ talerUri: "taler://pay",
+ proposalId: "fakeID",
+ contractTerms: {} as any,
+ amountRaw: hook.response.p2p.amount,
+ noncePriv: "",
+ } as any; //FIXME: check this interface with new values
+
+ const baseResult = {
+ uri: talerPayPullUri,
+ cancel: {
+ onClick: pushAlertOnError(onClose),
+ },
+ effective,
+ raw,
+ goToWalletManualWithdraw,
+ summary,
+ expiration: expiration
+ ? AbsoluteTime.fromProtocolTimestamp(expiration)
+ : undefined,
+ };
+
+ if (!foundBalance) {
+ return {
+ status: "no-balance-for-currency",
+ error: undefined,
+ balance: undefined,
+ ...baseResult,
+ payStatus: insufficientBalance,
+ };
+ }
+
+ const foundAmount = Amounts.parseOrThrow(foundBalance.available);
+
+ //FIXME: should use pay result type since it check for coins exceptions
+ if (Amounts.cmp(foundAmount, amount) < 0) {
+ //payStatus.status === PreparePayResultType.InsufficientBalance) {
+ return {
+ status: "no-enough-balance",
+ error: undefined,
+ balance: foundAmount,
+ ...baseResult,
+ payStatus: insufficientBalance,
+ };
+ }
+
+ async function accept(): Promise<void> {
+ const resp = await api.wallet.call(
+ WalletApiOperation.ConfirmPeerPullDebit,
+ {
+ transactionId,
+ },
+ );
+ onSuccess(resp.transactionId);
+ }
+
+ return {
+ status: "ready",
+ error: undefined,
+ ...baseResult,
+ payStatus: paymentPossible,
+ balance: foundAmount,
+ accept: {
+ onClick: pushAlertOnError(accept),
+ },
+ };
+}