aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts')
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts222
1 files changed, 103 insertions, 119 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
index 1b628047a..d7d9f2da7 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
@@ -29,13 +29,14 @@ import { alertFromError, useAlertContext } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
+import { RecursiveState } from "../../utils/index.js";
import { Props, State } from "./index.js";
export function useComponentState({
amount: amountStr,
onCancel,
onSuccess,
-}: Props): State {
+}: Props): RecursiveState<State> {
const api = useBackendContext();
const { i18n } = useTranslationContext();
const { pushAlertOnError } = useAlertContext();
@@ -49,9 +50,7 @@ export function useComponentState({
);
const { accounts } = await api.wallet.call(
WalletApiOperation.ListKnownBankAccounts,
- {
- currency,
- },
+ { currency },
);
return { accounts, balances };
@@ -61,13 +60,11 @@ export function useComponentState({
parsed !== undefined
? parsed
: currency !== undefined
- ? Amounts.zeroOfCurrency(currency)
- : undefined;
+ ? Amounts.zeroOfCurrency(currency)
+ : undefined;
// const [accountIdx, setAccountIdx] = useState<number>(0);
- const [amount, setAmount] = useState<AmountJson>(initialValue ?? ({} as any));
const [selectedAccount, setSelectedAccount] = useState<PaytoUri>();
- const [fee, setFee] = useState<DepositGroupFees | undefined>(undefined);
const [addingAccount, setAddingAccount] = useState(false);
if (!currency) {
@@ -91,7 +88,12 @@ export function useComponentState({
}
const { accounts, balances } = hook.response;
- // const parsedAmount = Amounts.parse(`${currency}:${amount}`);
+ async function updateAccountFromList(accountStr: string): Promise<void> {
+ const uri = !accountStr ? undefined : parsePaytoUri(accountStr);
+ if (uri) {
+ setSelectedAccount(uri);
+ }
+ }
if (addingAccount) {
return {
@@ -139,128 +141,110 @@ export function useComponentState({
const firstAccount = accounts[0].uri;
const currentAccount = !selectedAccount ? firstAccount : selectedAccount;
- if (fee === undefined) {
- getFeeForAmount(currentAccount, amount, api.wallet).then((initialFee) => {
- setFee(initialFee);
- });
- return {
- status: "loading",
- error: undefined,
- };
- }
+ return () => {
+ // eslint-disable-next-line react-hooks/rules-of-hooks
+ const [amount, setAmount] = useState<AmountJson>(
+ initialValue ?? ({} as any),
+ );
+ const amountStr = Amounts.stringify(amount);
+ const depositPaytoUri = `payto://${currentAccount.targetType}/${currentAccount.targetPath}`;
- const accountMap = createLabelsForBankAccount(accounts);
+ // eslint-disable-next-line react-hooks/rules-of-hooks
+ const hook = useAsyncAsHook(async () => {
+ const fee = await api.wallet.call(WalletApiOperation.GetFeeForDeposit, {
+ amount: amountStr,
+ depositPaytoUri,
+ });
- async function updateAccountFromList(accountStr: string): Promise<void> {
- const uri = !accountStr ? undefined : parsePaytoUri(accountStr);
- if (uri) {
- try {
- const result = await getFeeForAmount(uri, amount, api.wallet);
- setSelectedAccount(uri);
- setFee(result);
- } catch (e) {
- setSelectedAccount(uri);
- setFee(undefined);
- }
- }
- }
+ return { fee };
+ }, [amountStr, depositPaytoUri]);
- async function updateAmount(newAmount: AmountJson): Promise<void> {
- // const parsed = Amounts.parse(`${currency}:${numStr}`);
- try {
- const result = await getFeeForAmount(
- currentAccount,
- newAmount,
- api.wallet,
- );
- setAmount(newAmount);
- setFee(result);
- } catch (e) {
- setAmount(newAmount);
- setFee(undefined);
+ if (!hook) {
+ return {
+ status: "loading",
+ error: undefined,
+ };
+ }
+ if (hook.hasError) {
+ return {
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load fee for amount ${amountStr}`,
+ hook,
+ ),
+ };
}
- }
- const totalFee =
- fee !== undefined
- ? Amounts.sum([fee.wire, fee.coin, fee.refresh]).amount
- : Amounts.zeroOfCurrency(currency);
+ const { fee } = hook.response;
- const totalToDeposit =
- fee !== undefined
- ? Amounts.sub(amount, totalFee).amount
- : Amounts.zeroOfCurrency(currency);
+ const accountMap = createLabelsForBankAccount(accounts);
- const isDirty = amount !== initialValue;
- const amountError = !isDirty
- ? undefined
- : Amounts.cmp(balance, amount) === -1
- ? `Too much, your current balance is ${Amounts.stringifyValue(balance)}`
- : undefined;
+ const totalFee =
+ fee !== undefined
+ ? Amounts.sum([fee.wire, fee.coin, fee.refresh]).amount
+ : Amounts.zeroOfCurrency(currency);
- const unableToDeposit =
- Amounts.isZero(totalToDeposit) || //deposit may be zero because of fee
- fee === undefined || //no fee calculated yet
- amountError !== undefined; //amount field may be invalid
+ const totalToDeposit =
+ fee !== undefined
+ ? Amounts.sub(amount, totalFee).amount
+ : Amounts.zeroOfCurrency(currency);
- async function doSend(): Promise<void> {
- if (!currency) return;
+ const isDirty = amount !== initialValue;
+ const amountError = !isDirty
+ ? undefined
+ : Amounts.cmp(balance, amount) === -1
+ ? `Too much, your current balance is ${Amounts.stringifyValue(balance)}`
+ : undefined;
- const depositPaytoUri = stringifyPaytoUri(currentAccount);
- const amountStr = Amounts.stringify(amount);
- await api.wallet.call(WalletApiOperation.CreateDepositGroup, {
- amount: amountStr,
- depositPaytoUri,
- });
- onSuccess(currency);
- }
+ const unableToDeposit =
+ Amounts.isZero(totalToDeposit) || //deposit may be zero because of fee
+ fee === undefined || //no fee calculated yet
+ amountError !== undefined; //amount field may be invalid
- return {
- status: "ready",
- error: undefined,
- currency,
- amount: {
- value: amount,
- onInput: pushAlertOnError(updateAmount),
- error: amountError,
- },
- onAddAccount: {
- onClick: pushAlertOnError(async () => {
- setAddingAccount(true);
- }),
- },
- account: {
- list: accountMap,
- value: stringifyPaytoUri(currentAccount),
- onChange: pushAlertOnError(updateAccountFromList),
- },
- currentAccount,
- cancelHandler: {
- onClick: pushAlertOnError(async () => {
- onCancel(currency);
- }),
- },
- depositHandler: {
- onClick: unableToDeposit ? undefined : pushAlertOnError(doSend),
- },
- totalFee,
- totalToDeposit,
- // currentAccount,
- // parsedAmount,
- };
-}
+ async function doSend(): Promise<void> {
+ if (!currency) return;
-async function getFeeForAmount(
- p: PaytoUri,
- a: AmountJson,
- wallet: ReturnType<typeof useBackendContext>["wallet"],
-): Promise<DepositGroupFees> {
- const depositPaytoUri = `payto://${p.targetType}/${p.targetPath}`;
- const amount = Amounts.stringify(a);
- return await wallet.call(WalletApiOperation.GetFeeForDeposit, {
- amount,
- depositPaytoUri,
- });
+ const depositPaytoUri = stringifyPaytoUri(currentAccount);
+ const amountStr = Amounts.stringify(amount);
+ await api.wallet.call(WalletApiOperation.CreateDepositGroup, {
+ amount: amountStr,
+ depositPaytoUri,
+ });
+ onSuccess(currency);
+ }
+
+ return {
+ status: "ready",
+ error: undefined,
+ currency,
+ amount: {
+ value: amount,
+ onInput: pushAlertOnError(async (a) => setAmount(a)),
+ error: amountError,
+ },
+ onAddAccount: {
+ onClick: pushAlertOnError(async () => {
+ setAddingAccount(true);
+ }),
+ },
+ account: {
+ list: accountMap,
+ value: stringifyPaytoUri(currentAccount),
+ onChange: pushAlertOnError(updateAccountFromList),
+ },
+ currentAccount,
+ cancelHandler: {
+ onClick: pushAlertOnError(async () => {
+ onCancel(currency);
+ }),
+ },
+ depositHandler: {
+ onClick: unableToDeposit ? undefined : pushAlertOnError(doSend),
+ },
+ totalFee,
+ totalToDeposit,
+ };
+ };
}
export function labelForAccountType(id: string): string {