gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated (0f3b38745 -> f947c8e54)


From: gnunet
Subject: [taler-wallet-core] branch master updated (0f3b38745 -> f947c8e54)
Date: Sat, 01 Apr 2023 00:09:48 +0200

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a change to branch master
in repository wallet-core.

    from 0f3b38745 calculate deposit wire transfer
     new 8701ae100 calculation async
     new f947c8e54 calculate using server

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 packages/demobank-ui/src/declaration.d.ts          |   8 ++
 packages/demobank-ui/src/hooks/circuit.ts          | 105 +++++++++++++++++++++
 packages/demobank-ui/src/pages/BusinessAccount.tsx | 103 ++++++++++----------
 3 files changed, 165 insertions(+), 51 deletions(-)

diff --git a/packages/demobank-ui/src/declaration.d.ts 
b/packages/demobank-ui/src/declaration.d.ts
index 4d8484a4f..a37485272 100644
--- a/packages/demobank-ui/src/declaration.d.ts
+++ b/packages/demobank-ui/src/declaration.d.ts
@@ -329,6 +329,14 @@ namespace SandboxBackend {
       // where to send cashouts.
       cashout_address: string;
     }
+    interface CashoutEstimate {
+      // Amount that the user will get deducted from their regional
+      // bank account, according to the 'amount_credit' value.
+      amount_debit: Amount;
+      // Amount that the user will receive in their fiat
+      // bank account, according to 'amount_debit'.
+      amount_credit: Amount;
+    }
     interface CashoutRequest {
       // Optional subject to associate to the
       // cashout operation.  This data will appear
diff --git a/packages/demobank-ui/src/hooks/circuit.ts 
b/packages/demobank-ui/src/hooks/circuit.ts
index 137a7aee2..f90469e24 100644
--- a/packages/demobank-ui/src/hooks/circuit.ts
+++ b/packages/demobank-ui/src/hooks/circuit.ts
@@ -32,6 +32,7 @@ import {
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
 import _useSWR, { SWRHook } from "swr";
+import { AmountJson, Amounts } from "@gnu-taler/taler-util";
 const useSWR = _useSWR as unknown as SWRHook;
 
 export function useAdminAccountAPI(): AdminAccountAPI {
@@ -215,6 +216,23 @@ export interface CircuitAccountAPI {
 async function getBusinessStatus(
   request: ReturnType<typeof useApiContext>["request"],
   basicAuth: { username: string; password: string },
+): Promise<boolean> {
+  try {
+    const url = getInitialBackendBaseURL();
+    const result = await request<SandboxBackend.Circuit.CircuitAccountData>(
+      url,
+      `circuit-api/accounts/${basicAuth.username}`,
+      { basicAuth },
+    );
+    return result.ok;
+  } catch (error) {
+    return false;
+  }
+}
+
+async function getEstimationByCredit(
+  request: ReturnType<typeof useApiContext>["request"],
+  basicAuth: { username: string; password: string },
 ): Promise<boolean> {
   try {
     const url = getInitialBackendBaseURL();
@@ -227,6 +245,93 @@ async function getBusinessStatus(
   }
 }
 
+export type TransferCalculation = {
+  debit: AmountJson;
+  credit: AmountJson;
+  beforeFee: AmountJson;
+};
+type EstimatorFunction = (
+  amount: AmountJson,
+  sellFee: AmountJson,
+  sellRate: number,
+) => Promise<TransferCalculation>;
+
+type CashoutEstimators = {
+  estimateByCredit: EstimatorFunction;
+  estimateByDebit: EstimatorFunction;
+};
+
+export function useEstimator(): CashoutEstimators {
+  const { state } = useBackendContext();
+  const { request } = useApiContext();
+  const basicAuth =
+    state.status === "loggedOut"
+      ? undefined
+      : { username: state.username, password: state.password };
+  return {
+    estimateByCredit: async (amount, fee, rate) => {
+      const zeroBalance = Amounts.zeroOfCurrency(fee.currency);
+      const zeroFiat = Amounts.zeroOfCurrency(fee.currency);
+      const zeroCalc = {
+        debit: zeroBalance,
+        credit: zeroFiat,
+        beforeFee: zeroBalance,
+      };
+      const url = getInitialBackendBaseURL();
+      const result = await request<SandboxBackend.Circuit.CashoutEstimate>(
+        url,
+        `circuit-api/cashouts/estimates`,
+        {
+          basicAuth,
+          params: {
+            amount_credit: Amounts.stringify(amount),
+          },
+        },
+      );
+      // const credit = Amounts.parseOrThrow(result.data.data.amount_credit);
+      const credit = amount;
+      const _credit = { ...credit, currency: fee.currency };
+      const beforeFee = Amounts.sub(_credit, fee).amount;
+
+      const debit = Amounts.parseOrThrow(result.data.amount_debit);
+      return {
+        debit,
+        beforeFee,
+        credit,
+      };
+    },
+    estimateByDebit: async (amount, fee, rate) => {
+      const zeroBalance = Amounts.zeroOfCurrency(fee.currency);
+      const zeroFiat = Amounts.zeroOfCurrency(fee.currency);
+      const zeroCalc = {
+        debit: zeroBalance,
+        credit: zeroFiat,
+        beforeFee: zeroBalance,
+      };
+      const url = getInitialBackendBaseURL();
+      const result = await request<SandboxBackend.Circuit.CashoutEstimate>(
+        url,
+        `circuit-api/cashouts/estimates`,
+        {
+          basicAuth,
+          params: {
+            amount_debit: Amounts.stringify(amount),
+          },
+        },
+      );
+      const credit = Amounts.parseOrThrow(result.data.amount_credit);
+      const _credit = { ...credit, currency: fee.currency };
+      const debit = amount;
+      const beforeFee = Amounts.sub(_credit, fee).amount;
+      return {
+        debit,
+        beforeFee,
+        credit,
+      };
+    },
+  };
+}
+
 export function useBusinessAccountFlag(): boolean | undefined {
   const [isBusiness, setIsBusiness] = useState<boolean | undefined>();
   const { state } = useBackendContext();
diff --git a/packages/demobank-ui/src/pages/BusinessAccount.tsx 
b/packages/demobank-ui/src/pages/BusinessAccount.tsx
index 258802e58..262376fa2 100644
--- a/packages/demobank-ui/src/pages/BusinessAccount.tsx
+++ b/packages/demobank-ui/src/pages/BusinessAccount.tsx
@@ -26,7 +26,7 @@ import {
   useTranslationContext,
 } from "@gnu-taler/web-util/lib/index.browser";
 import { Fragment, h, VNode } from "preact";
-import { useEffect, useState } from "preact/hooks";
+import { useEffect, useMemo, useState } from "preact/hooks";
 import { Cashouts } from "../components/Cashouts/index.js";
 import { useBackendContext } from "../context/backend.js";
 import { ErrorMessage, usePageContext } from "../context/pageState.js";
@@ -34,6 +34,7 @@ import { useAccountDetails } from "../hooks/access.js";
 import {
   useCashoutDetails,
   useCircuitAccountAPI,
+  useEstimator,
   useRatiosAndFeeConfig,
 } from "../hooks/circuit.js";
 import {
@@ -230,7 +231,10 @@ function CreateCashout({
   const ratiosResult = useRatiosAndFeeConfig();
   const result = useAccountDetails(account);
   const [error, saveError] = useState<ErrorMessage | undefined>();
-
+  const {
+    estimateByCredit: calculateFromCredit,
+    estimateByDebit: calculateFromDebit,
+  } = useEstimator();
   const [form, setForm] = useState<Partial<FormType>>({ isDebit: true });
 
   const { createCashout } = useCircuitAccountAPI();
@@ -246,6 +250,8 @@ function CreateCashout({
     ? Amounts.sub(debitThreshold, balance).amount
     : Amounts.add(balance, debitThreshold).amount;
 
+  const zeroCalc = { debit: zero, credit: zero, beforeFee: zero };
+  const [calc, setCalc] = useState(zeroCalc);
   const sellRate = config.ratios_and_fees.sell_at_ratio;
   const sellFee = !config.ratios_and_fees.sell_out_fee
     ? zero
@@ -254,13 +260,47 @@ function CreateCashout({
 
   if (!sellRate || sellRate < 0) return <div>error rate</div>;
 
-  const amount = Amounts.parse(`${balance.currency}:${form.amount}`);
+  const amount = Amounts.parseOrThrow(
+    `${!form.isDebit ? fiatCurrency : balance.currency}:${
+      !form.amount ? "0" : form.amount
+    }`,
+  );
 
-  const calc = !amount
-    ? { debit: zero, credit: zero, beforeFee: zero }
-    : !form.isDebit
-    ? calculateFromCredit(amount, sellFee, sellRate)
-    : calculateFromDebit(amount, sellFee, sellRate);
+  useEffect(() => {
+    if (form.isDebit) {
+      calculateFromDebit(amount, sellFee, sellRate)
+        .then((r) => {
+          setCalc(r);
+          saveError(undefined);
+        })
+        .catch((error) => {
+          saveError(
+            error instanceof RequestError
+              ? buildRequestErrorMessage(i18n, error.cause)
+              : {
+                  title: i18n.str`Could not estimate the cashout`,
+                  description: error.message,
+                },
+          );
+        });
+    } else {
+      calculateFromCredit(amount, sellFee, sellRate)
+        .then((r) => {
+          setCalc(r);
+          saveError(undefined);
+        })
+        .catch((error) => {
+          saveError(
+            error instanceof RequestError
+              ? buildRequestErrorMessage(i18n, error.cause)
+              : {
+                  title: i18n.str`Could not estimate the cashout`,
+                  description: error.message,
+                },
+          );
+        });
+    }
+  }, [form.amount, form.isDebit]);
 
   const balanceAfter = Amounts.sub(balance, calc.debit).amount;
 
@@ -314,14 +354,10 @@ function CreateCashout({
               type="text"
               readonly
               class="currency-indicator"
-              size={
-                !form.isDebit ? fiatCurrency.length : balance.currency.length
-              }
-              maxLength={
-                !form.isDebit ? fiatCurrency.length : balance.currency.length
-              }
+              size={amount?.currency.length ?? 0}
+              maxLength={amount?.currency.length ?? 0}
               tabIndex={-1}
-              value={!form.isDebit ? fiatCurrency : balance.currency}
+              value={amount?.currency ?? ""}
             />
             &nbsp;
             <input
@@ -576,9 +612,7 @@ function CreateCashout({
               if (errors) return;
               try {
                 const res = await createCashout({
-                  amount_credit: `${fiatCurrency}:${Amounts.stringifyValue(
-                    calc.credit,
-                  )}`,
+                  amount_credit: Amounts.stringify(calc.credit),
                   amount_debit: Amounts.stringify(calc.debit),
                   subject: form.subject,
                   tan_channel: form.channel,
@@ -830,39 +864,6 @@ function truncate(a: AmountJson): AmountJson {
   return Amounts.parseOrThrow(truncated);
 }
 
-type TransferCalculation = {
-  debit: AmountJson;
-  credit: AmountJson;
-  beforeFee: AmountJson;
-};
-
-function calculateFromDebit(
-  amount: AmountJson,
-  sellFee: AmountJson,
-  sellRate: number,
-): TransferCalculation {
-  const debit = amount;
-
-  const beforeFee = truncate(Amounts.divide(debit, 1 / sellRate));
-
-  const credit = Amounts.sub(beforeFee, sellFee).amount;
-  return { debit, credit, beforeFee };
-}
-
-function calculateFromCredit(
-  amount: AmountJson,
-  sellFee: AmountJson,
-  sellRate: number,
-): TransferCalculation {
-  const credit = amount;
-
-  const beforeFee = Amounts.add(credit, sellFee).amount;
-
-  const debit = truncate(Amounts.divide(beforeFee, sellRate));
-
-  return { debit, credit, beforeFee };
-}
-
 export function assertUnreachable(x: never): never {
   throw new Error("Didn't expect to get here");
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]