From 689d58a5c79e98fec733c3cda31146620d8bde1d Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 10 Jun 2024 15:25:51 -0300 Subject: fix #8886 --- .../src/cta/Withdraw/index.ts | 3 + .../src/cta/Withdraw/state.ts | 128 ++++++++++++++------- .../src/cta/Withdraw/test.ts | 24 +++- .../src/cta/Withdraw/views.tsx | 7 +- packages/taler-wallet-webextension/src/wxApi.ts | 2 +- 5 files changed, 116 insertions(+), 48 deletions(-) (limited to 'packages/taler-wallet-webextension') diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts index 026a879df..af1ef213b 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts @@ -96,12 +96,15 @@ export namespace State { currentExchange: ExchangeListItem; amount: AmountFieldHandler; + editableAmount: boolean; + bankFee: AmountJson; withdrawalFee: AmountJson; toBeReceived: AmountJson; doWithdrawal: ButtonHandler; doSelectExchange: ButtonHandler; + editableExchange: boolean; chooseCurrencies: string[]; selectedCurrency: string; diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts index da3b1eeb2..f8e27e688 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -185,10 +185,16 @@ export function useComponentStateFromParams({ cancel, onSuccess, undefined, - chosenAmount, - chosenAmount.currency, - exchangeList, - exchangeByTalerUri, + { + amount: chosenAmount, + currency: chosenAmount.currency, + maxAmount: Amounts.zeroOfCurrency(chosenAmount.currency), + bankFee: Amounts.zeroOfCurrency(chosenAmount.currency), + editableAmount: true, + editableExchange: true, + exchange: exchangeByTalerUri, + exchangeList: exchangeList, + }, setUpdatedExchangeByUser, ); } @@ -215,13 +221,7 @@ export function useComponentStateFromURI({ WalletApiOperation.PrepareBankIntegratedWithdrawal, { talerWithdrawUri }, ); - const { - amount, - defaultExchangeBaseUrl, - possibleExchanges, - confirmTransferUrl, - status, - } = uriInfo.info; + const { status } = uriInfo.info; const txInfo = await api.wallet.call( WalletApiOperation.GetTransactionById, { @@ -232,12 +232,8 @@ export function useComponentStateFromURI({ talerWithdrawUri, status, transactionId: uriInfo.transactionId, - currency: uriInfo.info.currency, + bankWithdrawalInfo: uriInfo.info, txInfo: txInfo, - confirmTransferUrl, - amount: !amount ? undefined : Amounts.parseOrThrow(amount), - thisExchange: defaultExchangeBaseUrl, - exchanges: possibleExchanges, }; }); @@ -277,9 +273,22 @@ export function useComponentStateFromURI({ const uri = uriInfoHook.response.talerWithdrawUri; const txId = uriInfoHook.response.transactionId; - const infoAmount = uriInfoHook.response.amount; - const defaultExchange = uriInfoHook.response.thisExchange; - const exchangeList = uriInfoHook.response.exchanges; + const bwi = uriInfoHook.response.bankWithdrawalInfo; + + const amount = + bwi.amount === undefined + ? Amounts.zeroOfCurrency(bwi.currency) + : Amounts.parseOrThrow(bwi.amount); + + const maxAmount = + bwi.maxAmount === undefined + ? Amounts.zeroOfCurrency(bwi.currency) + : Amounts.parseOrThrow(bwi.maxAmount); + + const bankFee = + bwi.wireFee === undefined + ? Amounts.zeroOfCurrency(bwi.currency) + : Amounts.parseOrThrow(bwi.wireFee); async function doManagedWithdraw( exchange: string, @@ -309,7 +318,7 @@ export function useComponentStateFromURI({ return { status: "already-completed", operationState: uriInfoHook.response.status, - confirmTransferUrl: uriInfoHook.response.confirmTransferUrl, + confirmTransferUrl: bwi.confirmTransferUrl, thisWallet: info.txState.major === TransactionMajorState.Pending, redirectToTx: () => onSuccess(info.transactionId), error: undefined, @@ -322,15 +331,32 @@ export function useComponentStateFromURI({ cancel, onSuccess, uri, - infoAmount, - uriInfoHook.response.currency, - exchangeList, - defaultExchange, + { + amount, + bankFee, + maxAmount, + currency: bwi.currency, + editableAmount: bwi.editableAmount, + editableExchange: bwi.editableExchange, + exchange: bwi.defaultExchangeBaseUrl, + exchangeList: bwi.possibleExchanges, + }, setUpdatedExchangeByUser, ); }, []); } +type WithdrawalInfo = { + currency: string; + amount: AmountJson; + bankFee: AmountJson; + maxAmount: AmountJson; + editableAmount: boolean; + exchange: string | undefined; + editableExchange: boolean; + exchangeList: ExchangeListItem[]; +}; + type ManualOrManagedWithdrawFunction = ( exchange: string, ageRestricted: number | undefined, @@ -342,17 +368,14 @@ function exchangeSelectionState( cancel: () => Promise, onSuccess: (txid: string) => Promise, talerWithdrawUri: string | undefined, - infoAmount: AmountJson | undefined, - currency: string, - exchangeList: ExchangeListItem[], - exchangeSuggestedByTheBank: string | undefined, + wInfo: WithdrawalInfo, onExchangeUpdated: (ex: string) => void, ): RecursiveState { const api = useBackendContext(); const selectedExchange = useSelectedExchange({ - currency: currency, - defaultExchange: exchangeSuggestedByTheBank, - list: exchangeList, + currency: wInfo.currency, + defaultExchange: wInfo.exchange, + list: wInfo.exchangeList, }); const current = @@ -365,9 +388,9 @@ function exchangeSelectionState( } }, [current]); - const safeAmount = !infoAmount - ? Amounts.zeroOfCurrency(currency) - : infoAmount; + const safeAmount = wInfo.amount + ? wInfo.amount + : Amounts.zeroOfCurrency(wInfo.currency); const [choosenAmount, setChoosenAmount] = useState(safeAmount); if (selectedExchange.status !== "ready") { @@ -383,7 +406,9 @@ function exchangeSelectionState( const [ageRestricted, setAgeRestricted] = useState(0); const currentExchange = selectedExchange.selected; - const [selectedCurrency, setSelectedCurrency] = useState(currency); + const [selectedCurrency, setSelectedCurrency] = useState( + wInfo.currency, + ); /** * With the exchange and amount, ask the wallet the information * about the withdrawal @@ -456,6 +481,8 @@ function exchangeSelectionState( ).amount; const toBeReceived = amountHook.response.amount.effective; + const bankFee = wInfo.amount; + const ageRestrictionOptions = amountHook.response.ageRestrictionOptions?.reduce( (p, c) => ({ ...p, [c]: i18n.str`under ${c}` }), @@ -499,13 +526,26 @@ function exchangeSelectionState( amount: Amounts.parseOrThrow(convAccount.transferAmount!), }; + const amountError = Amounts.isZero(choosenAmount) + ? i18n.str`should be greater than zero` + : Amounts.cmp(choosenAmount, wInfo.maxAmount) === -1 + ? i18n.str`choose a lower value` + : undefined; + return { status: "success", error: undefined, - doSelectExchange: selectedExchange.doSelect, + doSelectExchange: { + onClick: wInfo.editableExchange + ? selectedExchange.doSelect.onClick + : undefined, + }, + editableAmount: wInfo.editableAmount, + editableExchange: wInfo.editableExchange, currentExchange, toBeReceived, chooseCurrencies, + bankFee, selectedCurrency, changeCurrency: (s) => { setSelectedCurrency(s); @@ -514,16 +554,20 @@ function exchangeSelectionState( withdrawalFee, amount: { value: choosenAmount, - onInput: pushAlertOnError(async (v) => { - setChoosenAmount(v); - }), + onInput: wInfo.editableAmount + ? pushAlertOnError(async (v) => { + setChoosenAmount(v); + }) + : undefined, + error: amountError, }, talerWithdrawUri, ageRestriction, doWithdrawal: { - onClick: doingWithdraw - ? undefined - : pushAlertOnError(doWithdrawAndCheckError), + onClick: + doingWithdraw && !amountError + ? undefined + : pushAlertOnError(doWithdrawAndCheckError), }, cancel, }; diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts index 5bbf5f6c8..bce5f71e3 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts @@ -119,7 +119,11 @@ describe("Withdraw CTA states", () => { currency: "ARS", amount: "EUR:2" as AmountString, possibleExchanges: [], - } + editableAmount: false, + editableExchange: false, + maxAmount: "ARS:1", + wireFee: "ARS:0", + }, }, ); @@ -162,7 +166,11 @@ describe("Withdraw CTA states", () => { amount: "ARS:2" as AmountString, possibleExchanges: exchanges, defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl, - } + editableAmount: false, + editableExchange: false, + maxAmount: "ARS:1", + wireFee: "ARS:0", + }, }, ); handler.addWalletCallResponse( @@ -176,7 +184,7 @@ describe("Withdraw CTA states", () => { scopeInfo: { currency: "ARS", type: ScopeType.Exchange, - url: "http://asd" + url: "http://asd", }, withdrawalAccountsList: [], ageRestrictionOptions: [], @@ -236,6 +244,10 @@ describe("Withdraw CTA states", () => { amount: "ARS:2" as AmountString, possibleExchanges: exchangeWithNewTos, defaultExchangeBaseUrl: exchangeWithNewTos[0].exchangeBaseUrl, + editableAmount: false, + editableExchange: false, + maxAmount: "ARS:1", + wireFee: "ARS:0", }, ); handler.addWalletCallResponse( @@ -248,7 +260,7 @@ describe("Withdraw CTA states", () => { scopeInfo: { currency: "ARS", type: ScopeType.Exchange, - url: "http://asd" + url: "http://asd", }, tosAccepted: false, withdrawalAccountsList: [], @@ -267,6 +279,10 @@ describe("Withdraw CTA states", () => { amount: "ARS:2" as AmountString, possibleExchanges: exchanges, defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl, + editableAmount: false, + editableExchange: false, + maxAmount: "ARS:1", + wireFee: "ARS:0", }, ); diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx index a4917446d..86d7248a4 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx @@ -19,6 +19,7 @@ import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { Amount } from "../../components/Amount.js"; import { AmountField } from "../../components/AmountField.js"; +import { EnabledBySettings } from "../../components/EnabledBySettings.js"; import { Part } from "../../components/Part.js"; import { QR } from "../../components/QR.js"; import { SelectList } from "../../components/SelectList.js"; @@ -38,7 +39,6 @@ import { getAmountWithFee, } from "../../wallet/Transaction.js"; import { State } from "./index.js"; -import { EnabledBySettings } from "../../components/EnabledBySettings.js"; export function FinalStateOperation(state: State.AlreadyCompleted): VNode { const { i18n } = useTranslationContext(); @@ -174,6 +174,11 @@ export function SuccessView(state: State.Success): VNode { kind="neutral" big /> + {state.editableAmount ? ( + + + + ) : undefined} {state.chooseCurrencies.length > 0 ? (

diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts index 4394a982f..47b466fcd 100644 --- a/packages/taler-wallet-webextension/src/wxApi.ts +++ b/packages/taler-wallet-webextension/src/wxApi.ts @@ -55,7 +55,7 @@ import { WalletActivityTrack } from "./wxBackend.js"; const logger = new Logger("wxApi"); -export const WALLET_CORE_SUPPORTED_VERSION = "4:0:0" +export const WALLET_CORE_SUPPORTED_VERSION = "5:0:0" export interface ExtendedPermissionsResponse { newValue: boolean; -- cgit v1.2.3