aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet')
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts2
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts68
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx15
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts57
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx13
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx15
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx1
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Transaction.tsx12
8 files changed, 95 insertions, 88 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
index 838739ad1..daba6aba4 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
@@ -94,9 +94,9 @@ export namespace State {
currentAccount: PaytoUri;
totalFee: AmountJson;
- totalToDeposit: AmountJson;
amount: AmountFieldHandler;
+ totalToDeposit: AmountFieldHandler;
account: SelectFieldHandler;
cancelHandler: ButtonHandler;
depositHandler: ButtonHandler;
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
index 97b2ab517..b674665cf 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
@@ -15,19 +15,18 @@
*/
import {
- AmountJson,
Amounts,
- DepositGroupFees,
KnownBankAccountsInfo,
parsePaytoUri,
PaytoUri,
stringifyPaytoUri,
+ TransactionAmountMode
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { useState } from "preact/hooks";
import { alertFromError, useAlertContext } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { RecursiveState } from "../../utils/index.js";
import { Props, State } from "./index.js";
@@ -83,8 +82,11 @@ export function useComponentState({
if (hook.hasError) {
return {
status: "error",
- error: alertFromError(i18n,
- i18n.str`Could not load balance information`, hook),
+ error: alertFromError(
+ i18n,
+ i18n.str`Could not load balance information`,
+ hook,
+ ),
};
}
const { accounts, balances } = hook.response;
@@ -141,21 +143,23 @@ export function useComponentState({
}
const firstAccount = accounts[0].uri;
const currentAccount = !selectedAccount ? firstAccount : selectedAccount;
-
- return () => {
- // eslint-disable-next-line react-hooks/rules-of-hooks
- const [amount, setAmount] = useState<AmountJson>(
- initialValue ?? ({} as any),
+ const zero = Amounts.zeroOfCurrency(currency)
+ return (): State => {
+ const [instructed, setInstructed] = useState(
+ {amount: initialValue ?? zero, type: TransactionAmountMode.Raw},
);
- const amountStr = Amounts.stringify(amount);
+ const amountStr = Amounts.stringify(instructed.amount);
const depositPaytoUri = stringifyPaytoUri(currentAccount);
- // eslint-disable-next-line react-hooks/rules-of-hooks
const hook = useAsyncAsHook(async () => {
- const fee = await api.wallet.call(WalletApiOperation.PrepareDeposit, {
- amount: amountStr,
- depositPaytoUri,
- });
+ const fee = await api.wallet.call(
+ WalletApiOperation.ConvertDepositAmount,
+ {
+ amount: amountStr,
+ type: instructed.type,
+ depositPaytoUri,
+ },
+ );
return { fee };
}, [amountStr, depositPaytoUri]);
@@ -183,18 +187,16 @@ export function useComponentState({
const totalFee =
fee !== undefined
- ? Amounts.sum([fee.fees.wire, fee.fees.coin, fee.fees.refresh]).amount
+ ? Amounts.sub(fee.effectiveAmount, fee.rawAmount).amount
: Amounts.zeroOfCurrency(currency);
- const totalToDeposit =
- fee !== undefined
- ? Amounts.sub(amount, totalFee).amount
- : Amounts.zeroOfCurrency(currency);
+ const totalToDeposit = Amounts.parseOrThrow(fee.rawAmount);
+ const totalEffective = Amounts.parseOrThrow(fee.effectiveAmount);
- const isDirty = amount !== initialValue;
+ const isDirty = instructed.amount !== initialValue;
const amountError = !isDirty
? undefined
- : Amounts.cmp(balance, amount) === -1
+ : Amounts.cmp(balance, totalEffective) === -1
? `Too much, your current balance is ${Amounts.stringifyValue(balance)}`
: undefined;
@@ -207,7 +209,7 @@ export function useComponentState({
if (!currency) return;
const depositPaytoUri = stringifyPaytoUri(currentAccount);
- const amountStr = Amounts.stringify(amount);
+ const amountStr = Amounts.stringify(totalEffective);
await api.wallet.call(WalletApiOperation.CreateDepositGroup, {
amount: amountStr,
depositPaytoUri,
@@ -220,8 +222,19 @@ export function useComponentState({
error: undefined,
currency,
amount: {
- value: amount,
- onInput: pushAlertOnError(async (a) => setAmount(a)),
+ value: totalEffective,
+ onInput: pushAlertOnError(async (a) => setInstructed({
+ amount: a,
+ type: TransactionAmountMode.Effective,
+ })),
+ error: amountError,
+ },
+ totalToDeposit: {
+ value: totalToDeposit,
+ onInput: pushAlertOnError(async (a) => setInstructed({
+ amount: a,
+ type: TransactionAmountMode.Raw,
+ })),
error: amountError,
},
onAddAccount: {
@@ -244,7 +257,6 @@ export function useComponentState({
onClick: unableToDeposit ? undefined : pushAlertOnError(doSend),
},
totalFee,
- totalToDeposit,
};
};
}
@@ -269,7 +281,7 @@ export function createLabelsForBankAccount(
): { [value: string]: string } {
const initialList: Record<string, string> = {};
if (!knownBankAccounts.length) return initialList;
- return knownBankAccounts.reduce((prev, cur, i) => {
+ return knownBankAccounts.reduce((prev, cur) => {
prev[stringifyPaytoUri(cur.uri)] = cur.alias;
return prev;
}, initialList);
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx
index c23f83fdd..0ed62220b 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx
@@ -53,7 +53,10 @@ export const WithNoAccountForIBAN = tests.createExample(ReadyView, {
onClick: nullFunction,
},
totalFee: Amounts.zeroOfCurrency("USD"),
- totalToDeposit: Amounts.parseOrThrow("USD:10"),
+ totalToDeposit: {
+ onInput:nullFunction,
+ value: Amounts.parseOrThrow("USD:10"),
+ },
// onCalculateFee: alwaysReturnFeeToOne,
});
@@ -82,7 +85,10 @@ export const WithIBANAccountTypeSelected = tests.createExample(ReadyView, {
onClick: nullFunction,
},
totalFee: Amounts.zeroOfCurrency("USD"),
- totalToDeposit: Amounts.parseOrThrow("USD:10"),
+ totalToDeposit: {
+ onInput:nullFunction,
+ value: Amounts.parseOrThrow("USD:10"),
+ },
// onCalculateFee: alwaysReturnFeeToOne,
});
@@ -111,6 +117,9 @@ export const NewBitcoinAccountTypeSelected = tests.createExample(ReadyView, {
onClick: nullFunction,
},
totalFee: Amounts.zeroOfCurrency("USD"),
- totalToDeposit: Amounts.parseOrThrow("USD:10"),
+ totalToDeposit: {
+ onInput:nullFunction,
+ value: Amounts.parseOrThrow("USD:10"),
+ },
// onCalculateFee: alwaysReturnFeeToOne,
});
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
index 157cb868a..1144095e1 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
@@ -20,17 +20,16 @@
*/
import {
+ AmountResponse,
Amounts,
AmountString,
- DepositGroupFees,
parsePaytoUri,
- PrepareDepositResponse,
ScopeType,
- stringifyPaytoUri,
+ stringifyPaytoUri
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
-import { expect } from "chai";
import * as tests from "@gnu-taler/web-util/testing";
+import { expect } from "chai";
import { nullFunction } from "../../mui/handlers.js";
import { createWalletApiMock } from "../../test-utils.js";
@@ -38,24 +37,14 @@ import { useComponentState } from "./state.js";
const currency = "EUR";
const amount = `${currency}:0`;
-const withoutFee = (): PrepareDepositResponse => ({
- effectiveDepositAmount: `${currency}:5` as AmountString,
- totalDepositCost: `${currency}:5` as AmountString,
- fees: {
- coin: Amounts.stringify(`${currency}:0`),
- wire: Amounts.stringify(`${currency}:0`),
- refresh: Amounts.stringify(`${currency}:0`),
- },
+const withoutFee = (value: number): AmountResponse => ({
+ effectiveAmount: `${currency}:${value}` as AmountString,
+ rawAmount: `${currency}:${value}` as AmountString,
});
-const withSomeFee = (): PrepareDepositResponse => ({
- effectiveDepositAmount: `${currency}:5` as AmountString,
- totalDepositCost: `${currency}:5` as AmountString,
- fees: {
- coin: Amounts.stringify(`${currency}:1`),
- wire: Amounts.stringify(`${currency}:1`),
- refresh: Amounts.stringify(`${currency}:1`),
- },
+const withSomeFee = (value: number, fee: number): AmountResponse => ({
+ effectiveAmount: `${currency}:${value}` as AmountString,
+ rawAmount: `${currency}:${value - fee}` as AmountString,
});
describe("DepositPage states", () => {
@@ -195,9 +184,9 @@ describe("DepositPage states", () => {
},
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withoutFee(),
+ withoutFee(0),
);
const hookBehavior = await tests.hookBehaveLikeThis(
@@ -255,15 +244,15 @@ describe("DepositPage states", () => {
},
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withoutFee(),
+ withoutFee(0),
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withoutFee(),
+ withoutFee(0),
);
const accountSelected = stringifyPaytoUri(ibanPayto.uri);
@@ -345,19 +334,19 @@ describe("DepositPage states", () => {
},
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withoutFee(),
+ withoutFee(0),
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withSomeFee(),
+ withSomeFee(10,3),
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withSomeFee(),
+ withSomeFee(10,3),
);
const accountSelected = stringifyPaytoUri(ibanPayto.uri);
@@ -404,7 +393,7 @@ describe("DepositPage states", () => {
expect(state.account.value).eq(accountSelected);
expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:10"));
expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`));
- expect(state.totalToDeposit).deep.eq(
+ expect(state.totalToDeposit.value).deep.eq(
Amounts.parseOrThrow(`${currency}:7`),
);
expect(state.depositHandler.onClick).not.undefined;
@@ -416,7 +405,7 @@ describe("DepositPage states", () => {
expect(state.account.value).eq(accountSelected);
expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:10"));
expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`));
- expect(state.totalToDeposit).deep.eq(
+ expect(state.totalToDeposit.value).deep.eq(
Amounts.parseOrThrow(`${currency}:7`),
);
expect(state.depositHandler.onClick).not.undefined;
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx
index 908becb04..b3607ebba 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx
@@ -26,7 +26,7 @@ import { Grid } from "../../mui/Grid.js";
import { State } from "./index.js";
export function AmountOrCurrencyErrorView(
- p: State.AmountOrCurrencyError,
+ _p: State.AmountOrCurrencyError,
): VNode {
const { i18n } = useTranslationContext();
@@ -145,7 +145,7 @@ export function ReadyView(state: State.Ready): VNode {
</p>
<Grid container spacing={2} columns={1}>
<Grid item xs={1}>
- <AmountField label={i18n.str`Amount`} handler={state.amount} />
+ <AmountField label={i18n.str`Brut amount`} handler={state.amount} />
</Grid>
<Grid item xs={1}>
<AmountField
@@ -156,12 +156,7 @@ export function ReadyView(state: State.Ready): VNode {
/>
</Grid>
<Grid item xs={1}>
- <AmountField
- label={i18n.str`Total deposit`}
- handler={{
- value: state.totalToDeposit,
- }}
- />
+ <AmountField label={i18n.str`Net amount`} handler={state.totalToDeposit} />
</Grid>
</Grid>
</section>
@@ -180,7 +175,7 @@ export function ReadyView(state: State.Ready): VNode {
) : (
<Button variant="contained" onClick={state.depositHandler.onClick}>
<i18n.Translate>
- Deposit&nbsp;{Amounts.stringifyValue(state.totalToDeposit)}{" "}
+ Deposit&nbsp;{Amounts.stringifyValue(state.totalToDeposit.value)}{" "}
{state.currency}
</i18n.Translate>
</Button>
diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
index 7b6ac8895..8f23c0685 100644
--- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
@@ -17,13 +17,12 @@
import {
AbsoluteTime,
Amounts,
- CoinDumpJson,
CoinStatus,
ExchangeTosStatus,
LogLevel,
NotificationType,
ScopeType,
- stringifyWithdrawExchange,
+ stringifyWithdrawExchange
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useTranslationContext } from "@gnu-taler/web-util/browser";
@@ -52,7 +51,6 @@ import { Grid } from "../mui/Grid.js";
import { Paper } from "../mui/Paper.js";
import { TextField } from "../mui/TextField.js";
-type CoinsInfo = CoinDumpJson["coins"];
type CalculatedCoinfInfo = {
// ageKeysCount: number | undefined;
denom_value: number;
@@ -68,15 +66,7 @@ type SplitedCoinInfo = {
usable: CalculatedCoinfInfo[];
};
-export interface Props {
- // FIXME: Pending operations don't exist anymore.
-}
-
-function hashObjectId(o: any): string {
- return JSON.stringify(o);
-}
-
-export function DeveloperPage({}: Props): VNode {
+export function DeveloperPage(): VNode {
const { i18n } = useTranslationContext();
const [downloadedDatabase, setDownloadedDatabase] = useState<
{ time: Date; content: string } | undefined
@@ -361,6 +351,7 @@ export function DeveloperPage({}: Props): VNode {
<a
href={new URL(`/keys`, e.exchangeBaseUrl).href}
target="_blank"
+ rel="noreferrer"
>
{e.exchangeBaseUrl}
</a>
diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx b/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx
index 7b80977f3..b995a44d0 100644
--- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx
@@ -130,7 +130,6 @@ export function ReadyView({
))}
</div>
<div style={{ border: "1px solid gray", padding: 8, borderRadius: 5 }}>
- --- {uri.value} ---
<p>
<CustomFieldByAccountType
type={accountType.value as AccountType}
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
index 1f0293352..ca5bc3756 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
@@ -1416,9 +1416,11 @@ export function TransferPickupDetails({
export function WithdrawDetails({
conversion,
amount,
+ bankFee,
}: {
conversion?: AmountJson;
amount: AmountWithFee;
+ bankFee?: AmountJson;
}): VNode {
const { i18n } = useTranslationContext();
@@ -1481,6 +1483,16 @@ export function WithdrawDetails({
</tr>
</Fragment>
)}
+ {!bankFee ? undefined : (
+ <tr>
+ <td>
+ <i18n.Translate>Bank fee</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={bankFee} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ )}
</PurchaseDetailsTable>
);
}