aboutsummaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-08-09 11:07:06 -0300
committerSebastian <sebasjm@gmail.com>2024-08-09 11:14:45 -0300
commit93f1f9867a6f5681df847d60efca4828f5d49deb (patch)
tree4b2851ac0f96ce62fb46a4c3e9cd61f38a3258a8 /packages
parent085a1e6be0b9ed3d2439588b43675777661efb33 (diff)
scoped p2p
Diffstat (limited to 'packages')
-rw-r--r--packages/taler-wallet-webextension/src/NavigationBar.tsx5
-rw-r--r--packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts7
-rw-r--r--packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts82
-rw-r--r--packages/taler-wallet-webextension/src/cta/InvoiceCreate/stories.tsx7
-rw-r--r--packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx9
-rw-r--r--packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts6
-rw-r--r--packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts98
-rw-r--r--packages/taler-wallet-webextension/src/cta/TransferCreate/stories.tsx7
-rw-r--r--packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx9
-rw-r--r--packages/taler-wallet-webextension/src/platform/firefox.ts3
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Application.tsx79
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts3
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts47
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts38
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts12
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts101
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx16
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts6
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx72
19 files changed, 205 insertions, 402 deletions
diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx b/packages/taler-wallet-webextension/src/NavigationBar.tsx
index efdd6c2d7..d045bc1e3 100644
--- a/packages/taler-wallet-webextension/src/NavigationBar.tsx
+++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx
@@ -114,8 +114,7 @@ export const Pages = {
),
balanceDeposit: pageDefinition<{
scope: CrockEncodedString;
- amount?: string;
- }>("/balance/deposit/:scope/:amount?"),
+ }>("/balance/deposit/:scope"),
sendCash: pageDefinition<{ scope: CrockEncodedString; amount?: string }>(
"/destination/send/:scope/:amount?",
),
@@ -157,11 +156,9 @@ export const Pages = {
ctaAddExchange: "/cta/add/exchange",
ctaInvoiceCreate: pageDefinition<{
scope: CrockEncodedString;
- amount?: string;
}>("/cta/invoice/create/:scope/:amount?"),
ctaTransferCreate: pageDefinition<{
scope: CrockEncodedString;
- amount?: string;
}>("/cta/transfer/create/:scope/:amount?"),
ctaInvoicePay: "/cta/invoice/pay",
ctaTransferPickup: "/cta/transfer/pickup",
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts
index 1ca7481be..dbca08b2b 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts
@@ -14,12 +14,12 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { AmountJson, AmountString } from "@gnu-taler/taler-util";
+import { AmountJson, AmountString, ScopeInfo } from "@gnu-taler/taler-util";
import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
import { ErrorAlert } from "../../context/alert.js";
import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js";
-import { ButtonHandler, TextFieldHandler } from "../../mui/handlers.js";
+import { AmountFieldHandler, ButtonHandler, TextFieldHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { ExchangeSelectionPage } from "../../wallet/ExchangeSelection/index.js";
import { NoExchangesView } from "../../wallet/ExchangeSelection/views.js";
@@ -27,7 +27,7 @@ import { useComponentState } from "./state.js";
import { ReadyView } from "./views.js";
export interface Props {
- amount: AmountString;
+ scope: ScopeInfo;
onClose: () => Promise<void>;
onSuccess: (tx: string) => Promise<void>;
}
@@ -59,6 +59,7 @@ export namespace State {
status: "ready";
doSelectExchange: ButtonHandler;
create: ButtonHandler;
+ amount: AmountFieldHandler;
subject: TextFieldHandler;
expiration: TextFieldHandler;
toBeReceived: AmountJson;
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
index baaa9a3dd..d2db4f44c 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
@@ -15,7 +15,7 @@
*/
/* eslint-disable react-hooks/rules-of-hooks */
-import { Amounts, TalerProtocolTimestamp } from "@gnu-taler/taler-util";
+import { AmountJson, Amounts, AmountString, TalerProtocolTimestamp } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { isFuture, parse } from "date-fns";
import { useState } from "preact/hooks";
@@ -28,11 +28,10 @@ import { RecursiveState } from "../../utils/index.js";
import { Props, State } from "./index.js";
export function useComponentState({
- amount: amountStr,
+ scope,
onClose,
onSuccess,
}: Props): RecursiveState<State> {
- const amount = Amounts.parseOrThrow(amountStr);
const api = useBackendContext();
const { pushAlertOnError } = useAlertContext();
@@ -72,12 +71,14 @@ export function useComponentState({
const exchangeList = hook.response.exchanges;
return () => {
+ const [amount, setAmount] = useState<AmountJson>(Amounts.zeroOfCurrency(scope.currency));
const [subject, setSubject] = useState<string | undefined>();
const [timestamp, setTimestamp] = useState<string | undefined>();
const { pushAlertOnError } = useAlertContext();
+ const amountStr = Amounts.stringify(amount)
const selectedExchange = useSelectedExchange({
- currency: amount.currency,
+ currency: scope.currency,
defaultExchange: undefined,
list: exchangeList,
});
@@ -97,39 +98,41 @@ export function useComponentState({
},
);
return resp;
- });
-
- if (!hook) {
- return {
- status: "loading",
- error: undefined,
- };
- }
-
- if (hook.hasError) {
- return {
- status: "error",
- retry: {
- onClick: pushAlertOnError(async () => {
- hook.retry();
- }),
- },
- error: alertFromError(
- i18n,
- i18n.str`Could not load the invoice status`,
- hook,
- ),
- };
- // return {
- // status: "loading-uri",
- // error: hook,
- // };
- }
-
- const { amountEffective, amountRaw } = hook.response;
- const requestAmount = Amounts.parseOrThrow(amountRaw);
- const toBeReceived = Amounts.parseOrThrow(amountEffective);
-
+ },[amountStr]);
+
+ // if (!hook) {
+ // return {
+ // status: "loading",
+ // error: undefined,
+ // };
+ // }
+
+ // if (hook.hasError) {
+ // return {
+ // status: "error",
+ // retry: {
+ // onClick: pushAlertOnError(async () => {
+ // hook.retry();
+ // }),
+ // },
+ // error: alertFromError(
+ // i18n,
+ // i18n.str`Could not load the invoice status`,
+ // hook,
+ // ),
+ // };
+ // // return {
+ // // status: "loading-uri",
+ // // error: hook,
+ // // };
+ // }
+
+ // const { amountEffective, amountRaw } = hook.response;
+ // const requestAmount = Amounts.parseOrThrow(amountRaw);
+ // const toBeReceived = Amounts.parseOrThrow(amountEffective);
+ const requestAmount = !hook || hook.hasError ? Amounts.zeroOfCurrency(scope.currency) : Amounts.parseOrThrow(hook.response.amountRaw);
+ const toBeReceived = !hook || hook.hasError ? Amounts.zeroOfCurrency(scope.currency) : Amounts.parseOrThrow(hook.response.amountEffective);
+
let purse_expiration: TalerProtocolTimestamp | undefined = undefined;
let timestampError: string | undefined = undefined;
@@ -174,6 +177,11 @@ export function useComponentState({
return {
status: "ready",
+ amount: {
+ value: amount,
+ onInput: pushAlertOnError(async (e) => setAmount(e)),
+ error: Amounts.isZero(amount) ? "Can't be zero" : undefined,
+ },
subject: {
error:
subject === undefined
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/stories.tsx b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/stories.tsx
index 779f130aa..9822f7c91 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/stories.tsx
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/stories.tsx
@@ -33,6 +33,13 @@ export const Ready = tests.createExample(ReadyView, {
value: 1,
fraction: 0,
},
+ amount: {
+ value: {
+ currency: "ARS",
+ value: 1,
+ fraction: 0,
+ }
+ },
expiration: {
value: "2/12/12",
},
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx
index e2c37fbba..86bac5a16 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx
@@ -27,10 +27,12 @@ import {
InvoiceCreationDetails,
} from "../../wallet/Transaction.js";
import { State } from "./index.js";
+import { AmountField } from "../../components/AmountField.js";
export function ReadyView({
exchangeUrl,
subject,
+ amount,
expiration,
create,
toBeReceived,
@@ -87,6 +89,13 @@ export function ReadyView({
big
/>
<p>
+ <AmountField
+ label={i18n.str`Amount`}
+ handler={amount}
+ required
+ />
+ </p>
+ <p>
<TextField
label="Subject"
variant="filled"
diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts
index 539ca207c..2969efb7f 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts
@@ -17,18 +17,19 @@
import {
AmountJson,
AmountString,
+ ScopeInfo,
TalerErrorDetail,
} from "@gnu-taler/taler-util";
import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
import { ErrorAlert } from "../../context/alert.js";
-import { ButtonHandler, TextFieldHandler } from "../../mui/handlers.js";
+import { AmountFieldHandler, ButtonHandler, TextFieldHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
import { ReadyView } from "./views.js";
export interface Props {
- amount: AmountString;
+ scope: ScopeInfo;
onClose: () => Promise<void>;
onSuccess: (tx: string) => Promise<void>;
}
@@ -54,6 +55,7 @@ export namespace State {
export interface Ready extends BaseInfo {
status: "ready";
create: ButtonHandler;
+ amount: AmountFieldHandler;
toBeReceived: AmountJson;
debitAmount: AmountJson;
subject: TextFieldHandler;
diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts
index f15d48c23..1a8f318c0 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts
@@ -15,64 +15,42 @@
*/
import {
- AmountString,
+ AmountJson,
Amounts,
- TalerErrorCode,
- TalerProtocolTimestamp,
+ TalerProtocolTimestamp
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { isFuture, parse } from "date-fns";
-import { useState } from "preact/hooks";
+import { useEffect, useState } from "preact/hooks";
import { alertFromError, useAlertContext } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
-import { BackgroundError, WxApiType } from "../../wxApi.js";
import { Props, State } from "./index.js";
export function useComponentState({
- amount: amountStr,
+ scope,
onClose,
onSuccess,
}: Props): State {
const api = useBackendContext();
const { pushAlertOnError } = useAlertContext();
- const amount = Amounts.parseOrThrow(amountStr);
+ // const amount = Amounts.parseOrThrow(amountStr);
const { i18n } = useTranslationContext();
+ const [amount, setAmount] = useState<AmountJson>(Amounts.zeroOfCurrency(scope.currency));
const [subject, setSubject] = useState<string | undefined>();
const [timestamp, setTimestamp] = useState<string | undefined>();
+ const amountStr = Amounts.stringify(amount)
const hook = useAsyncAsHook(async () => {
- const resp = await checkPeerPushDebitAndCheckMax(api, amountStr);
- return resp;
- });
-
- if (!hook) {
- return {
- status: "loading",
- error: undefined,
- };
- }
- if (hook.hasError) {
- return {
- status: "error",
- retry: {
- onClick: pushAlertOnError(async () => {
- hook.retry();
- }),
- },
- error: alertFromError(
- i18n,
- i18n.str`Could not load the max amount to transfer`,
- hook,
- ),
- };
- }
+ return await api.wallet.call(WalletApiOperation.CheckPeerPushDebit, {
+ amount: amountStr,
+ });
+ }, [amountStr]);
- const { amountEffective, amountRaw } = hook.response;
- const debitAmount = Amounts.parseOrThrow(amountEffective);
- const toBeReceived = Amounts.parseOrThrow(amountRaw);
+ const debitAmount = !hook || hook.hasError ? Amounts.zeroOfCurrency(scope.currency) : Amounts.parseOrThrow(hook.response.amountEffective);
+ const toBeReceived = !hook || hook.hasError ? Amounts.zeroOfCurrency(scope.currency) : Amounts.parseOrThrow(hook.response.amountRaw);
let purse_expiration: TalerProtocolTimestamp | undefined = undefined;
let timestampError: string | undefined = undefined;
@@ -112,13 +90,18 @@ export function useComponentState({
}
const unableToCreate =
- !subject || Amounts.isZero(amount) || !purse_expiration;
+ !subject || Amounts.isZero(amount) || Amounts.isZero(debitAmount) || !purse_expiration;
return {
status: "ready",
cancel: {
onClick: pushAlertOnError(onClose),
},
+ amount: {
+ value: amount,
+ onInput: pushAlertOnError(async (e) => setAmount(e)),
+ error: Amounts.isZero(amount) ? "Can't be zero" : undefined,
+ },
subject: {
error:
subject === undefined
@@ -145,46 +128,3 @@ export function useComponentState({
};
}
-async function checkPeerPushDebitAndCheckMax(
- api: WxApiType,
- amountState: AmountString,
-) {
- // FIXME : https://bugs.gnunet.org/view.php?id=7872
- try {
- return await api.wallet.call(WalletApiOperation.CheckPeerPushDebit, {
- amount: amountState,
- });
- } catch (e) {
- if (!(e instanceof BackgroundError)) {
- throw e;
- }
- if (
- !e.hasErrorCode(
- TalerErrorCode.WALLET_PEER_PUSH_PAYMENT_INSUFFICIENT_BALANCE,
- )
- ) {
- throw e;
- }
- const material = Amounts.parseOrThrow(
- e.errorDetail.insufficientBalanceDetails.balanceMaterial,
- );
- const amount = Amounts.parseOrThrow(amountState);
- const gap = Amounts.sub(
- amount,
- Amounts.parseOrThrow(
- e.errorDetail.insufficientBalanceDetails.maxEffectiveSpendAmount,
- ),
- ).amount;
- const newAmount = Amounts.sub(material, gap).amount;
- if (Amounts.cmp(newAmount, amount) === 0) {
- //insufficient balance and the exception didn't give
- //a good response that allow us to try again
- throw e;
- }
- if (Amounts.cmp(newAmount, amount) === 1) {
- //how can this happen?
- throw e;
- }
- return checkPeerPushDebitAndCheckMax(api, Amounts.stringify(newAmount));
- }
-}
diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/stories.tsx b/packages/taler-wallet-webextension/src/cta/TransferCreate/stories.tsx
index 8e9fbbe63..9ba806ba4 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferCreate/stories.tsx
+++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/stories.tsx
@@ -33,6 +33,13 @@ export const Ready = tests.createExample(ReadyView, {
value: 1,
fraction: 0,
},
+ amount: {
+ value: {
+ currency: "ARS",
+ value: 1,
+ fraction: 0,
+ }
+ },
expiration: {
value: "20/1/2022",
},
diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx b/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx
index bc855f33d..269f39fbe 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx
@@ -25,9 +25,11 @@ import {
TransferCreationDetails,
} from "../../wallet/Transaction.js";
import { State } from "./index.js";
+import { AmountField } from "../../components/AmountField.js";
export function ReadyView({
subject,
+ amount,
expiration,
toBeReceived,
debitAmount,
@@ -61,6 +63,13 @@ export function ReadyView({
<Fragment>
<section style={{ textAlign: "left" }}>
<p>
+ <AmountField
+ label={i18n.str`Amount`}
+ handler={amount}
+ required
+ />
+ </p>
+ <p>
<TextField
label="Subject"
variant="filled"
diff --git a/packages/taler-wallet-webextension/src/platform/firefox.ts b/packages/taler-wallet-webextension/src/platform/firefox.ts
index 3d67423fd..4292bd7fd 100644
--- a/packages/taler-wallet-webextension/src/platform/firefox.ts
+++ b/packages/taler-wallet-webextension/src/platform/firefox.ts
@@ -18,9 +18,8 @@ import {
BackgroundPlatformAPI,
CrossBrowserPermissionsApi,
ForegroundPlatformAPI,
- Permissions,
Settings,
- defaultSettings,
+ defaultSettings
} from "./api.js";
import chromePlatform, {
containsClipboardPermissions as chromeClipContains,
diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx
index 5b789c25e..1b14236d5 100644
--- a/packages/taler-wallet-webextension/src/wallet/Application.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx
@@ -192,7 +192,7 @@ export function Application(): VNode {
goToWalletManualWithdraw={(scope?: ScopeInfo) =>
redirectTo(
Pages.receiveCash({
- scope: !scope?undefined:encodeCrockForURI(stringifyScopeInfoShort(scope)),
+ scope: !scope ? undefined : encodeCrockForURI(stringifyScopeInfoShort(scope)),
}),
)
}
@@ -225,7 +225,7 @@ export function Application(): VNode {
goToWalletManualWithdraw={(scope?: ScopeInfo) =>
redirectTo(
Pages.receiveCash({
- scope: !scope? undefined: encodeCrockForURI(stringifyScopeInfoShort(scope)),
+ scope: !scope ? undefined : encodeCrockForURI(stringifyScopeInfoShort(scope)),
}),
)
}
@@ -237,10 +237,8 @@ export function Application(): VNode {
path={Pages.sendCash.pattern}
component={({
scope,
- amount,
}: {
scope?: string;
- amount: string;
}) => {
if (!scope) return <Redirect to={Pages.balanceHistory({})} />;
const s = parseScopeInfoShort(decodeCrockFromURI(scope));
@@ -251,20 +249,17 @@ export function Application(): VNode {
<DestinationSelectionPage
type="send"
scope={s}
- amount={!amount ? undefined : Amounts.parse(amount)}
- goToWalletBankDeposit={(s, amount: string) =>
+ goToWalletBankDeposit={(s) =>
redirectTo(
Pages.balanceDeposit({
scope: encodeCrockForURI(stringifyScopeInfoShort(s)),
- amount,
}),
)
}
- goToWalletWalletSend={(s, amount: string) =>
+ goToWalletWalletSend={(s) =>
redirectTo(
Pages.ctaTransferCreate({
scope: encodeCrockForURI(stringifyScopeInfoShort(s)),
- amount,
}),
)
}
@@ -297,10 +292,8 @@ export function Application(): VNode {
path={Pages.receiveCash.pattern}
component={({
scope,
- amount,
}: {
scope?: string;
- amount?: string;
}) => {
const s = !scope
? undefined
@@ -311,20 +304,17 @@ export function Application(): VNode {
<DestinationSelectionPage
type="get"
scope={s}
- amount={!amount ? undefined : Amounts.parse(amount)}
- goToWalletManualWithdraw={(s, amount?: string) =>
+ goToWalletManualWithdraw={(s,) =>
redirectTo(
Pages.ctaWithdrawManual({
scope: encodeCrockForURI(stringifyScopeInfoShort(s)),
- amount,
}),
)
}
- goToWalletWalletInvoice={(s, amount?: string) =>
+ goToWalletWalletInvoice={(s,) =>
redirectTo(
Pages.ctaInvoiceCreate({
scope: encodeCrockForURI(stringifyScopeInfoShort(s)),
- amount,
}),
)
}
@@ -356,32 +346,33 @@ export function Application(): VNode {
path={Pages.balanceDeposit.pattern}
component={({
scope,
- amount,
}: {
scope: string;
- amount?: string;
- }) => (
- <WalletTemplate path="balance" goToURL={redirectToURL}>
- <DepositPage
- scope={parseScopeInfoShort(decodeCrockFromURI(scope))}
- amount={!amount ? undefined : Amounts.parse(amount)}
- onCancel={(scope: ScopeInfo) => {
- redirectTo(
- Pages.balanceHistory({
- scope: encodeCrockForURI(stringifyScopeInfoShort(scope)),
- }),
- );
- }}
- onSuccess={(scope: ScopeInfo) => {
- redirectTo(
- Pages.balanceHistory({
- scope: encodeCrockForURI(stringifyScopeInfoShort(scope)),
- }),
- );
- }}
- />
- </WalletTemplate>
- )}
+ }) => {
+ const s = parseScopeInfoShort(decodeCrockFromURI(scope))
+ if (!s) {
+ return <div>missing scope</div>
+ }
+ return <WalletTemplate path="balance" goToURL={redirectToURL}>
+ <DepositPage
+ scope={s}
+ onCancel={(scope: ScopeInfo) => {
+ redirectTo(
+ Pages.balanceHistory({
+ scope: encodeCrockForURI(stringifyScopeInfoShort(scope)),
+ }),
+ );
+ }}
+ onSuccess={(scope: ScopeInfo) => {
+ redirectTo(
+ Pages.balanceHistory({
+ scope: encodeCrockForURI(stringifyScopeInfoShort(scope)),
+ }),
+ );
+ }}
+ />
+ </WalletTemplate>
+ }}
/>
<Route
@@ -595,10 +586,10 @@ export function Application(): VNode {
/>
<Route
path={Pages.ctaInvoiceCreate.pattern}
- component={({ amount }: { amount: string }) => (
+ component={({ scope }: { scope: string }) => (
<CallToActionTemplate title={i18n.str`Digital cash invoice`}>
<InvoiceCreatePage
- amount={Amounts.stringify(Amounts.parseOrThrow(amount))}
+ scope={parseScopeInfoShort(decodeCrockFromURI(scope))!}
onClose={() => redirectTo(Pages.balance)}
onSuccess={(tid: string) =>
redirectTo(Pages.balanceTransaction({ tid }))
@@ -609,10 +600,10 @@ export function Application(): VNode {
/>
<Route
path={Pages.ctaTransferCreate.pattern}
- component={({ amount }: { amount: string }) => (
+ component={({ scope }: { scope: string }) => (
<CallToActionTemplate title={i18n.str`Digital cash transfer`}>
<TransferCreatePage
- amount={Amounts.stringify(Amounts.parseOrThrow(amount))}
+ scope={parseScopeInfoShort(decodeCrockFromURI(scope))!}
onClose={() => redirectTo(Pages.balance)}
onSuccess={(tid: string) =>
redirectTo(Pages.balanceTransaction({ tid }))
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
index 11642861a..e26992688 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
@@ -34,8 +34,7 @@ import {
} from "./views.js";
export interface Props {
- scope?:ScopeInfo;
- amount?: AmountJson;
+ scope:ScopeInfo;
onCancel: (scope: ScopeInfo) => void;
onSuccess: (scope: ScopeInfo) => void;
}
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
index f45c9ddd5..37f078ff6 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
@@ -32,7 +32,6 @@ import { RecursiveState } from "../../utils/index.js";
import { Props, State } from "./index.js";
export function useComponentState({
- amount,
scope,
onCancel,
onSuccess,
@@ -40,40 +39,29 @@ export function useComponentState({
const api = useBackendContext();
const { i18n } = useTranslationContext();
const { pushAlertOnError } = useAlertContext();
- const parsed = amount;
- const currency = parsed !== undefined ? parsed.currency : undefined;
+
+ const zero = Amounts.zeroOfCurrency(scope.currency);
+
const hook = useAsyncAsHook(async () => {
const { balances } = await api.wallet.call(
WalletApiOperation.GetBalances,
- {},
+ {
+ },
);
+
const { accounts } = await api.wallet.call(
WalletApiOperation.ListKnownBankAccounts,
- { currency },
+ { currency: scope.currency },
);
return { accounts, balances };
});
- const initialValue =
- parsed !== undefined
- ? parsed
- : currency !== undefined
- ? Amounts.zeroOfCurrency(currency)
- : undefined;
- // const [accountIdx, setAccountIdx] = useState<number>(0);
const [selectedAccount, setSelectedAccount] = useState<PaytoUri>();
const [addingAccount, setAddingAccount] = useState(false);
- if (!currency) {
- return {
- status: "amount-or-currency-error",
- error: undefined,
- };
- }
-
if (!hook) {
return {
status: "loading",
@@ -103,7 +91,7 @@ export function useComponentState({
return {
status: "manage-account",
error: undefined,
- currency,
+ currency: scope.currency,
onAccountAdded: (p: string) => {
updateAccountFromList(p);
setAddingAccount(false);
@@ -116,17 +104,17 @@ export function useComponentState({
};
}
- const bs = balances.filter((b) => b.available.startsWith(currency));
+ const bs = balances.filter((b) => b.scopeInfo === scope);
const balance =
bs.length > 0
? Amounts.parseOrThrow(bs[0].available)
- : Amounts.zeroOfCurrency(currency);
+ : Amounts.zeroOfCurrency(scope.currency);
if (Amounts.isZero(balance)) {
return {
status: "no-enough-balance",
error: undefined,
- currency,
+ currency: scope.currency,
};
}
@@ -134,7 +122,7 @@ export function useComponentState({
return {
status: "no-accounts",
error: undefined,
- currency,
+ currency: scope.currency,
onAddAccount: {
onClick: pushAlertOnError(async () => {
setAddingAccount(true);
@@ -144,10 +132,9 @@ export function useComponentState({
}
const firstAccount = accounts[0].uri;
const currentAccount = !selectedAccount ? firstAccount : selectedAccount;
- const zero = Amounts.zeroOfCurrency(currency)
return (): State => {
const [instructed, setInstructed] = useState(
- {amount: initialValue ?? zero, type: TransactionAmountMode.Raw},
+ { amount: zero, type: TransactionAmountMode.Raw },
);
const amountStr = Amounts.stringify(instructed.amount);
const depositPaytoUri = stringifyPaytoUri(currentAccount);
@@ -189,12 +176,12 @@ export function useComponentState({
const totalFee =
fee !== undefined
? Amounts.sub(fee.effectiveAmount, fee.rawAmount).amount
- : Amounts.zeroOfCurrency(currency);
+ : zero;
const totalToDeposit = Amounts.parseOrThrow(fee.rawAmount);
const totalEffective = Amounts.parseOrThrow(fee.effectiveAmount);
- const isDirty = instructed.amount !== initialValue;
+ const isDirty = instructed.amount !== zero;
const amountError = !isDirty
? undefined
: Amounts.cmp(balance, totalEffective) === -1
@@ -207,7 +194,7 @@ export function useComponentState({
amountError !== undefined; //amount field may be invalid
async function doSend(): Promise<void> {
- if (!currency) return;
+ // if (!currency) return;
const depositPaytoUri = stringifyPaytoUri(currentAccount);
const amountStr = Amounts.stringify(totalEffective);
@@ -221,7 +208,7 @@ export function useComponentState({
return {
status: "ready",
error: undefined,
- currency,
+ currency: scope.currency,
amount: {
value: totalEffective,
onInput: pushAlertOnError(async (a) => setInstructed({
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
index 7f22ea0ed..a96f09553 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
@@ -67,11 +67,7 @@ describe("DepositPage states", () => {
pendingIncoming: `${currency}:0` as AmountString,
pendingOutgoing: `${currency}:0` as AmountString,
requiresUserInput: false,
- scopeInfo: {
- currency,
- type: ScopeType.Auditor,
- url: "asd",
- },
+ scopeInfo: defaultScope,
},
],
});
@@ -103,7 +99,7 @@ describe("DepositPage states", () => {
it("should have status 'no-accounts' when balance is not empty and accounts is empty", async () => {
const { handler, TestingContext } = createWalletApiMock();
- const props = { amount, onCancel: nullFunction, onSuccess: nullFunction };
+ const props = { scope: defaultScope, onCancel: nullFunction, onSuccess: nullFunction };
handler.addWalletCallResponse(WalletApiOperation.GetBalances, undefined, {
balances: [
@@ -114,11 +110,7 @@ describe("DepositPage states", () => {
pendingIncoming: `${currency}:0` as AmountString,
pendingOutgoing: `${currency}:0` as AmountString,
requiresUserInput: false,
- scopeInfo: {
- currency,
- type: ScopeType.Auditor,
- url: "asd",
- },
+ scopeInfo: defaultScope,
},
],
});
@@ -163,7 +155,7 @@ describe("DepositPage states", () => {
it("should have status 'ready' but unable to deposit ", async () => {
const { handler, TestingContext } = createWalletApiMock();
- const props = { amount, onCancel: nullFunction, onSuccess: nullFunction };
+ const props = { scope: defaultScope, onCancel: nullFunction, onSuccess: nullFunction };
handler.addWalletCallResponse(WalletApiOperation.GetBalances, undefined, {
balances: [
@@ -174,11 +166,7 @@ describe("DepositPage states", () => {
pendingIncoming: `${currency}:0` as AmountString,
pendingOutgoing: `${currency}:0` as AmountString,
requiresUserInput: false,
- scopeInfo: {
- currency,
- type: ScopeType.Auditor,
- url: "asd",
- },
+ scopeInfo: defaultScope,
},
],
});
@@ -223,7 +211,7 @@ describe("DepositPage states", () => {
it("should not be able to deposit more than the balance ", async () => {
const { handler, TestingContext } = createWalletApiMock();
- const props = { amount, onCancel: nullFunction, onSuccess: nullFunction };
+ const props = { scope: defaultScope, onCancel: nullFunction, onSuccess: nullFunction };
handler.addWalletCallResponse(WalletApiOperation.GetBalances, undefined, {
balances: [
@@ -234,11 +222,7 @@ describe("DepositPage states", () => {
pendingIncoming: `${currency}:0` as AmountString,
pendingOutgoing: `${currency}:0` as AmountString,
requiresUserInput: false,
- scopeInfo: {
- currency,
- type: ScopeType.Auditor,
- url: "asd",
- },
+ scopeInfo: defaultScope,
},
],
});
@@ -313,7 +297,7 @@ describe("DepositPage states", () => {
it("should calculate the fee upon entering amount ", async () => {
const { handler, TestingContext } = createWalletApiMock();
- const props = { amount, onCancel: nullFunction, onSuccess: nullFunction };
+ const props = { scope: defaultScope, onCancel: nullFunction, onSuccess: nullFunction };
handler.addWalletCallResponse(WalletApiOperation.GetBalances, undefined, {
balances: [
@@ -324,11 +308,7 @@ describe("DepositPage states", () => {
pendingIncoming: `${currency}:0` as AmountString,
pendingOutgoing: `${currency}:0` as AmountString,
requiresUserInput: false,
- scopeInfo: {
- currency,
- type: ScopeType.Auditor,
- url: "asd",
- },
+ scopeInfo: defaultScope,
},
],
});
diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts
index 74726fc30..befff87ff 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts
@@ -31,16 +31,14 @@ export type Props = PropsGet | PropsSend;
interface PropsGet {
type: "get";
scope?: ScopeInfo;
- amount?: AmountJson;
- goToWalletManualWithdraw: (s:ScopeInfo, amount: string) => void;
- goToWalletWalletInvoice: (s:ScopeInfo, amount: string) => void;
+ goToWalletManualWithdraw: (s:ScopeInfo) => void;
+ goToWalletWalletInvoice: (s:ScopeInfo) => void;
}
interface PropsSend {
type: "send";
scope: ScopeInfo;
- amount?: AmountJson;
- goToWalletBankDeposit: (s:ScopeInfo, amount: string) => void;
- goToWalletWalletSend: (s:ScopeInfo, amount: string) => void;
+ goToWalletBankDeposit: (s:ScopeInfo) => void;
+ goToWalletWalletSend: (s:ScopeInfo) => void;
}
export type State =
@@ -72,11 +70,9 @@ export namespace State {
error: undefined;
type: Props["type"];
selectCurrency: ButtonHandler;
- selectMax: ButtonHandler;
previous: Contact[];
goToBank: ButtonHandler;
goToWallet: ButtonHandler;
- amountHandler: AmountFieldHandler;
}
}
diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts
index dd15b9106..e138b28fb 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts
@@ -37,11 +37,6 @@ export function useComponentState(props: Props): RecursiveState<State> {
const [scope, setScope] = useState(props.scope);
- const [amount, setAmount] = useState<AmountJson | undefined>(
- props.amount ??
- (scope ? Amounts.zeroOfCurrency(scope.currency) : undefined),
- );
-
// const scopeStr = !scope ? undefined : stringifyScopeInfoShort(scope);
// useEffect(() => {
// if (!scope) return;
@@ -55,24 +50,24 @@ export function useComponentState(props: Props): RecursiveState<State> {
const previous: Contact[] = true
? []
: [
- {
- name: "International Bank",
- icon_type: "bank",
- description: "account ending with 3454",
- },
- {
- name: "Max",
- icon_type: "bank",
- description: "account ending with 3454",
- },
- {
- name: "Alex",
- icon_type: "bank",
- description: "account ending with 3454",
- },
- ];
-
- if (!scope || !amount) {
+ {
+ name: "International Bank",
+ icon_type: "bank",
+ description: "account ending with 3454",
+ },
+ {
+ name: "Max",
+ icon_type: "bank",
+ description: "account ending with 3454",
+ },
+ {
+ name: "Alex",
+ icon_type: "bank",
+ description: "account ending with 3454",
+ },
+ ];
+
+ if (!scope) {
return () => {
const { i18n } = useTranslationContext();
const hook = useAsyncAsHook(async () => {
@@ -137,16 +132,12 @@ export function useComponentState(props: Props): RecursiveState<State> {
onCurrencySelected: (c: string) => {
const scope = parseScopeInfoShort(c);
setScope(scope);
- setAmount(scope ? Amounts.zeroOfCurrency(scope.currency) : undefined);
},
currencies,
};
};
}
- const currencyAndAmount = Amounts.stringify(amount);
- const invalid = Amounts.isZero(amount);
-
switch (props.type) {
case "send":
return {
@@ -155,40 +146,18 @@ export function useComponentState(props: Props): RecursiveState<State> {
previous,
selectCurrency: {
onClick: pushAlertOnError(async () => {
- setAmount(undefined);
setScope(undefined);
}),
},
goToBank: {
- onClick: invalid
- ? undefined
- : pushAlertOnError(async () => {
- props.goToWalletBankDeposit(scope, currencyAndAmount);
- }),
- },
- selectMax: {
onClick: pushAlertOnError(async () => {
- const resp = await api.wallet.call(
- WalletApiOperation.GetMaxDepositAmount,
- {
- currency: amount.currency,
- },
- );
- setAmount(Amounts.parseOrThrow(resp.effectiveAmount));
+ props.goToWalletBankDeposit(scope);
}),
},
goToWallet: {
- onClick: invalid
- ? undefined
- : pushAlertOnError(async () => {
- props.goToWalletWalletSend(scope, currencyAndAmount);
- }),
- },
- amountHandler: {
- onInput: pushAlertOnError(async (s) => {
- setAmount(s);
+ onClick: pushAlertOnError(async () => {
+ props.goToWalletWalletSend(scope);
}),
- value: amount,
},
type: props.type,
};
@@ -199,34 +168,18 @@ export function useComponentState(props: Props): RecursiveState<State> {
previous,
selectCurrency: {
onClick: pushAlertOnError(async () => {
- setAmount(undefined);
setScope(undefined);
}),
},
- selectMax: {
- onClick: invalid
- ? undefined
- : pushAlertOnError(async () => {
- props.goToWalletManualWithdraw(scope, currencyAndAmount);
- }),
- },
goToBank: {
- onClick: invalid
- ? undefined
- : pushAlertOnError(async () => {
- props.goToWalletManualWithdraw(scope, currencyAndAmount);
- }),
+ onClick: pushAlertOnError(async () => {
+ props.goToWalletManualWithdraw(scope);
+ }),
},
goToWallet: {
- onClick: invalid
- ? undefined
- : pushAlertOnError(async () => {
- props.goToWalletWalletInvoice(scope, currencyAndAmount);
- }),
- },
- amountHandler: {
- onInput: pushAlertOnError(async (s) => setAmount(s)),
- value: amount,
+ onClick: pushAlertOnError(async () => {
+ props.goToWalletWalletInvoice(scope);
+ }),
},
type: props.type,
};
diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx
index e1ac958f7..0e68f2019 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx
@@ -27,29 +27,13 @@ export default {
};
export const GetCash = tests.createExample(ReadyView, {
- amountHandler: {
- value: {
- currency: "EUR",
- fraction: 0,
- value: 2,
- },
- },
goToBank: {},
- selectMax: {},
goToWallet: {},
previous: [],
selectCurrency: {},
type: "get",
});
export const SendCash = tests.createExample(ReadyView, {
- amountHandler: {
- value: {
- currency: "EUR",
- fraction: 0,
- value: 1,
- },
- },
- selectMax: {},
goToBank: {},
goToWallet: {},
previous: [],
diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts
index e7b277752..9e75f0b6f 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts
@@ -98,9 +98,6 @@ describe("Destination selection states", () => {
expect(state.goToBank.onClick).eq(undefined);
expect(state.goToWallet.onClick).eq(undefined);
- expect(state.amountHandler.value).deep.eq(
- Amounts.parseOrThrow("ARS:0"),
- );
},
],
TestingContext,
@@ -138,9 +135,6 @@ describe("Destination selection states", () => {
expect(state.goToBank.onClick).not.eq(undefined);
expect(state.goToWallet.onClick).not.eq(undefined);
- expect(state.amountHandler.value).deep.eq(
- Amounts.parseOrThrow("ARS:2"),
- );
},
],
TestingContext,
diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
index 497e1c786..cc368992d 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
@@ -192,10 +192,8 @@ export function ReadyView(props: State.Ready): VNode {
}
}
export function ReadyGetView({
- amountHandler,
goToBank,
goToWallet,
- selectCurrency,
previous,
}: State.Ready): VNode {
const { i18n } = useTranslationContext();
@@ -203,19 +201,8 @@ export function ReadyGetView({
return (
<Container>
<h1>
- <i18n.Translate>Specify the amount and the origin</i18n.Translate>
+ <i18n.Translate>Specify the origin</i18n.Translate>
</h1>
- <Grid container columns={2} justifyContent="space-between">
- <AmountField
- label={i18n.str`Amount`}
- required
- handler={amountHandler}
- />
-
- <Button onClick={selectCurrency.onClick}>
- <i18n.Translate>Change currency</i18n.Translate>
- </Button>
- </Grid>
<Grid container spacing={1} columns={1}>
{previous.length > 0 ? (
@@ -231,7 +218,7 @@ export function ReadyGetView({
<td>
<RowExample
info={info}
- disabled={!amountHandler.onInput}
+ // disabled={!amountHandler.onInput}
/>
</td>
</tr>
@@ -241,26 +228,11 @@ export function ReadyGetView({
</Grid>
</Fragment>
) : undefined}
- {previous.length > 0 ? (
- <Grid item>
- <p>
- <i18n.Translate>
- Or specify the origin of the money
- </i18n.Translate>
- </p>
- </Grid>
- ) : (
- <Grid item>
- <p>
- <i18n.Translate>Specify the origin of the money</i18n.Translate>
- </p>
- </Grid>
- )}
<Grid item container columns={2} spacing={1}>
<Grid item xs={1}>
<Paper style={{ padding: 8 }}>
<p>
- <i18n.Translate>From my bank account</i18n.Translate>
+ <i18n.Translate>From another bank account</i18n.Translate>
</p>
<Button onClick={goToBank.onClick}>
<i18n.Translate>Withdraw</i18n.Translate>
@@ -293,33 +265,18 @@ export function ReadyGetView({
);
}
export function ReadySendView({
- amountHandler,
goToBank,
goToWallet,
previous,
- selectMax,
}: State.Ready): VNode {
const { i18n } = useTranslationContext();
return (
<Container>
<h1>
- <i18n.Translate>Specify the amount and the destination</i18n.Translate>
+ <i18n.Translate>Specify the destination</i18n.Translate>
</h1>
- <Grid container columns={2} justifyContent="space-between">
- <AmountField
- label={i18n.str`Amount`}
- required
- handler={amountHandler}
- />
- <EnabledBySettings name="advancedMode">
- <Button onClick={selectMax.onClick}>
- <i18n.Translate>Send all</i18n.Translate>
- </Button>
- </EnabledBySettings>
- </Grid>
-
<Grid container spacing={1} columns={1}>
{previous.length > 0 ? (
<Fragment>
@@ -334,7 +291,7 @@ export function ReadySendView({
<td>
<RowExample
info={info}
- disabled={!amountHandler.onInput}
+ // disabled={!amountHandler.onInput}
/>
</td>
</tr>
@@ -344,28 +301,11 @@ export function ReadySendView({
</Grid>
</Fragment>
) : undefined}
- {previous.length > 0 ? (
- <Grid item>
- <p>
- <i18n.Translate>
- Or specify the destination of the money
- </i18n.Translate>
- </p>
- </Grid>
- ) : (
- <Grid item>
- <p>
- <i18n.Translate>
- Specify the destination of the money
- </i18n.Translate>
- </p>
- </Grid>
- )}
<Grid item container columns={2} spacing={1}>
<Grid item xs={1}>
<Paper style={{ padding: 8 }}>
<p>
- <i18n.Translate>To my bank account</i18n.Translate>
+ <i18n.Translate>To another bank account</i18n.Translate>
</p>
<Button onClick={goToBank.onClick}>
<i18n.Translate>Deposit</i18n.Translate>