From 1faa908c22c5833e75e94b07118b87eb2de3596a Mon Sep 17 00:00:00 2001
From: Sebastian
Date: Wed, 13 Mar 2024 09:54:41 -0300
Subject: fix #8460
---
.../bank-ui/src/components/Transactions/state.ts | 2 +-
.../bank-ui/src/components/Transactions/views.tsx | 2 +-
.../bank-ui/src/pages/PaytoWireTransferForm.tsx | 236 +++++++++++++--------
packages/bank-ui/src/pages/SolveChallengePage.tsx | 1 -
packages/bank-ui/src/pages/WalletWithdrawForm.tsx | 14 +-
.../src/pages/WithdrawalConfirmationQuestion.tsx | 74 +++++--
.../src/pages/account/ShowAccountDetails.tsx | 224 ++++++++++++++++++-
packages/bank-ui/src/pages/admin/DownloadStats.tsx | 6 +-
.../src/pages/regional/ConversionConfig.tsx | 4 +-
.../bank-ui/src/pages/regional/CreateCashout.tsx | 26 +--
.../src/pages/regional/ShowCashoutDetails.tsx | 2 +-
.../src/wallet/ManageAccount/stories.tsx | 4 +
12 files changed, 460 insertions(+), 135 deletions(-)
(limited to 'packages')
diff --git a/packages/bank-ui/src/components/Transactions/state.ts b/packages/bank-ui/src/components/Transactions/state.ts
index e792ddfa0..4e4552a82 100644
--- a/packages/bank-ui/src/components/Transactions/state.ts
+++ b/packages/bank-ui/src/components/Transactions/state.ts
@@ -55,7 +55,7 @@ export function useComponentState({
: cp.targetType === "x-taler-bank"
? cp.account
: cp.targetType === "bitcoin"
- ? `${cp.targetPath.substring(0, 6)}...`
+ ? `${cp.address.substring(0, 6)}...`
: undefined) ?? "unknown";
const when = AbsoluteTime.fromProtocolTimestamp(tx.date);
diff --git a/packages/bank-ui/src/components/Transactions/views.tsx b/packages/bank-ui/src/components/Transactions/views.tsx
index da64efdb2..4397651e2 100644
--- a/packages/bank-ui/src/components/Transactions/views.tsx
+++ b/packages/bank-ui/src/components/Transactions/views.tsx
@@ -120,7 +120,7 @@ export function ReadyView({
diff --git a/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx b/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx
index d5bb5f88f..7812a1da0 100644
--- a/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx
+++ b/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx
@@ -78,7 +78,6 @@ export function PaytoWireTransferForm({
onAuthorizationRequired,
limit,
}: Props): VNode {
-
const [inputType, setInputType] = useState<"form" | "payto" | "qr">("form");
const isRawPayto = inputType !== "form";
@@ -150,7 +149,7 @@ export function PaytoWireTransferForm({
: p.targetType === "iban"
? p.iban
: p.targetType === "bitcoin"
- ? p.targetPath
+ ? p.address
: p.targetType === "x-taler-bank"
? p.account
: assertUnreachable(p);
@@ -215,7 +214,8 @@ export function PaytoWireTransferForm({
case TalerErrorCode.BANK_UNKNOWN_CREDITOR:
return notify({
type: "error",
- title: i18n.str`The destination account "${acName ?? puri}" was not found.`,
+ title: i18n.str`The destination account "${acName ?? puri
+ }" was not found.`,
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
when: AbsoluteTime.now(),
@@ -351,106 +351,168 @@ export function PaytoWireTransferForm({
Input wire transfer detail
-
- {
- if (parsed && parsed.isKnown) {
- switch (parsed.targetType) {
- case "iban": {
- setAccount(parsed.iban);
- break;
- }
- case "x-taler-bank": {
- setAccount(parsed.account);
- break;
- }
- case "bitcoin": {
- break;
+
+ {
+ if (parsed && parsed.isKnown) {
+ switch (parsed.targetType) {
+ case "iban": {
+ setAccount(parsed.iban);
+ break;
+ }
+ case "x-taler-bank": {
+ setAccount(parsed.account);
+ break;
+ }
+ case "bitcoin": {
+ break;
+ }
+ default: {
+ assertUnreachable(parsed);
+ }
}
- default: {
- assertUnreachable(parsed);
+ const amountStr = !parsed.params
+ ? undefined
+ : parsed.params["amount"];
+ if (amountStr) {
+ const amount = Amounts.parse(amountStr);
+ if (amount) {
+ setAmount(Amounts.stringifyValue(amount));
+ }
}
- }
- const amountStr = !parsed.params
- ? undefined
- : parsed.params["amount"];
- if (amountStr) {
- const amount = Amounts.parse(amountStr);
- if (amount) {
- setAmount(Amounts.stringifyValue(amount));
+ const subject = parsed.params["message"];
+ if (subject) {
+ setSubject(subject);
}
}
- const subject = parsed.params["message"];
- if (subject) {
- setSubject(subject);
- }
- }
- setInputType("form")
- }} checked={inputType === "form"} value="form" class="mt-0.5 h-4 w-4 shrink-0 cursor-pointer text-indigo-600 border-gray-300 focus:ring-indigo-600 active:ring-2 active:ring-offset-2 active:ring-indigo-600" />
+ setInputType("form");
+ }}
+ checked={inputType === "form"}
+ value="form"
+ class="mt-0.5 h-4 w-4 shrink-0 cursor-pointer text-indigo-600 border-gray-300 focus:ring-indigo-600 active:ring-2 active:ring-offset-2 active:ring-indigo-600"
+ />
{/* */}
-
+
Using a form
- {sendingToFixedAccount ? undefined : (
-
- {
- if (account) {
- let payto;
- switch (paytoType) {
- case "x-taler-bank": {
- payto = buildPayto("x-taler-bank", url.host, account);
- if (parsedAmount) {
- payto.params["amount"] =
- Amounts.stringify(parsedAmount);
- }
- if (subject) {
- payto.params["message"] = subject;
- }
- break;
- }
- case "iban": {
- payto = buildPayto("iban", account, undefined);
- if (parsedAmount) {
- payto.params["amount"] =
- Amounts.stringify(parsedAmount);
- }
- if (subject) {
- payto.params["message"] = subject;
+ {sendingToFixedAccount ? undefined : (
+
+
+ {
+ if (account) {
+ let payto;
+ switch (paytoType) {
+ case "x-taler-bank": {
+ payto = buildPayto(
+ "x-taler-bank",
+ url.host,
+ account,
+ );
+ if (parsedAmount) {
+ payto.params["amount"] =
+ Amounts.stringify(parsedAmount);
+ }
+ if (subject) {
+ payto.params["message"] = subject;
+ }
+ break;
+ }
+ case "iban": {
+ payto = buildPayto("iban", account, undefined);
+ if (parsedAmount) {
+ payto.params["amount"] =
+ Amounts.stringify(parsedAmount);
+ }
+ if (subject) {
+ payto.params["message"] = subject;
+ }
+ break;
+ }
+ default:
+ assertUnreachable(paytoType);
}
- break;
+ rawPaytoInputSetter(stringifyPaytoUri(payto));
}
- default:
- assertUnreachable(paytoType);
- }
- rawPaytoInputSetter(stringifyPaytoUri(payto));
- } setInputType("payto")
- }} checked={inputType === "payto"} value="payto" class="mt-0.5 h-4 w-4 shrink-0 cursor-pointer text-indigo-600 border-gray-300 focus:ring-indigo-600 active:ring-2 active:ring-offset-2 active:ring-indigo-600" />
-
- payto:// URI
-
- A special URI that indicate the transfer amount and account target.
-
-
-
- { //FIXME: add QR support
- false &&
- {
- setInputType("qr")
- }} checked={inputType === "qr"} value="qr" class="mt-0.5 h-4 w-4 shrink-0 cursor-pointer text-indigo-600 border-gray-300 focus:ring-indigo-600 active:ring-2 active:ring-offset-2 active:ring-indigo-600" />
+ setInputType("payto");
+ }}
+ checked={inputType === "payto"}
+ value="payto"
+ class="mt-0.5 h-4 w-4 shrink-0 cursor-pointer text-indigo-600 border-gray-300 focus:ring-indigo-600 active:ring-2 active:ring-offset-2 active:ring-indigo-600"
+ />
-
- QR code
+
+ payto:// URI
-
- If you have a camera in this device you can import a payto:// URI from a QR code.
+
+
+ A special URI that indicate the transfer amount and
+ account target.
+
- }
- )}
-
+ {
+ //FIXME: add QR support
+ false && (
+
+ {
+ setInputType("qr");
+ }}
+ checked={inputType === "qr"}
+ value="qr"
+ class="mt-0.5 h-4 w-4 shrink-0 cursor-pointer text-indigo-600 border-gray-300 focus:ring-indigo-600 active:ring-2 active:ring-offset-2 active:ring-indigo-600"
+ />
+
+
+ QR code
+
+
+
+ If you have a camera in this device you can import a
+ payto:// URI from a QR code.
+
+
+
+
+ )
+ }
+
+ )}
{routeCashout ? (
Cashout
) : undefined}
-
-
-
diff --git a/packages/bank-ui/src/pages/WalletWithdrawForm.tsx b/packages/bank-ui/src/pages/WalletWithdrawForm.tsx
index 8e9529190..2aa0338ad 100644
--- a/packages/bank-ui/src/pages/WalletWithdrawForm.tsx
+++ b/packages/bank-ui/src/pages/WalletWithdrawForm.tsx
@@ -105,12 +105,12 @@ function OldWithdrawalForm({
class="font-semibold text-yellow-700 hover:text-yellow-600"
name="complete operation"
href={url}
- // onClick={(e) => {
- // e.preventDefault()
- // walletInegrationApi.publishTalerAction(uri, () => {
- // navigateTo(url)
- // })
- // }}
+ // onClick={(e) => {
+ // e.preventDefault()
+ // walletInegrationApi.publishTalerAction(uri, () => {
+ // navigateTo(url)
+ // })
+ // }}
>
this page
@@ -392,7 +392,7 @@ export function WalletWithdrawForm({
routeClose={routeCancel}
routeHere={routeOperationDetails}
onAbort={onOperationAborted}
- // route={routeCancel}
+ // route={routeCancel}
/>
)}
diff --git a/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx b/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
index 965650eb0..c7bdaaf21 100644
--- a/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
+++ b/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
@@ -222,10 +222,21 @@ export function WithdrawalConfirmationQuestion({
{((): VNode => {
+ if (!details.account.isKnown) {
+ return
+
+
+ Payment provider's account
+
+
+
+ {details.account.targetPath}
+
+
+ }
switch (details.account.targetType) {
case "iban": {
- const p = details.account as PaytoUriIBAN;
- const name = p.params["receiver-name"];
+ const name = details.account.params["receiver-name"];
return (
@@ -235,7 +246,7 @@ export function WithdrawalConfirmationQuestion({
- {p.iban}
+ {details.account.iban}
{name && (
@@ -254,10 +265,19 @@ export function WithdrawalConfirmationQuestion({
);
}
case "x-taler-bank": {
- const p = details.account as PaytoUriTalerBank;
- const name = p.params["receiver-name"];
+ const name = details.account.params["receiver-name"];
return (
+
+
+
+ Payment provider's account bank hostname
+
+
+
+ {details.account.host}
+
+
@@ -265,7 +285,7 @@ export function WithdrawalConfirmationQuestion({
- {p.account}
+ {details.account.account}
{name && (
@@ -283,19 +303,39 @@ export function WithdrawalConfirmationQuestion({
);
}
- default:
+ case "bitcoin": {
+ const name = details.account.params["receiver-name"];
return (
-
-
-
- Payment provider's account
-
-
-
- {details.account.targetPath}
-
-
+
+
+
+
+ Payment provider's account address
+
+
+
+ {details.account.address}
+
+
+ {name && (
+
+
+
+ Payment provider's name
+
+
+
+ {name}
+
+
+ )}
+
);
+ }
+ default: {
+ assertUnreachable(details.account)
+ }
+
}
})()}
diff --git a/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx b/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx
index e81d46d77..13685c2c8 100644
--- a/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx
+++ b/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx
@@ -19,10 +19,13 @@ import {
TalerCorebankApi,
TalerError,
TalerErrorCode,
+ TalerRevenueHttpClient,
TranslatedString,
assertUnreachable,
+ parsePaytoUri,
} from "@gnu-taler/taler-util";
import {
+ CopyButton,
Loading,
LocalNotificationBanner,
notifyInfo,
@@ -67,7 +70,7 @@ export function ShowAccountDetails({
const { i18n } = useTranslationContext();
const { state: credentials } = useSessionState();
const creds = credentials.status !== "loggedIn" ? undefined : credentials;
- const { bank: api } = useBankCoreApiContext();
+ const { bank } = useBankCoreApiContext();
const accountIsTheCurrentUser =
credentials.status === "loggedIn"
? credentials.username === account
@@ -99,7 +102,7 @@ export function ShowAccountDetails({
async function doUpdate() {
if (!submitAccount || !creds) return;
await handleError(async () => {
- const resp = await api.updateAccount(
+ const resp = await bank.updateAccount(
{
token: creds.token,
username: account,
@@ -186,6 +189,31 @@ export function ShowAccountDetails({
});
}
+
+ const url = bank.getRevenueAPI(account)
+ url.username = account;
+ const baseURL = url.href;
+
+ const ac = parsePaytoUri(result.body.payto_uri);
+ const payto = !ac?.isKnown ? undefined : ac;
+ let accountLetter: string | undefined = undefined;
+ if (payto) {
+ switch (payto.targetType) {
+ case "iban": {
+ accountLetter = `account-info-url=${url.href}\naccount-type=${payto.targetType}\niban=${payto.iban}\nreceiver-name=${result.body.name}\n`;
+ break;
+ }
+ case "x-taler-bank": {
+ accountLetter = `account-info-url=${url.href}\naccount-type=${payto.targetType}\naccount=${payto.account}\nhost=${payto.host}\nreceiver-name=${result.body.name}\n`;
+ break;
+ }
+ case "bitcoin": {
+ accountLetter = `account-info-url=${url.href}\naccount-type=${payto.targetType}\naddress=${payto.address}\nreceiver-name=${result.body.name}\n`;
+ break;
+ }
+ }
+ }
+
return (
@@ -247,6 +275,198 @@ export function ShowAccountDetails({
+
+
+
+
+
+
+ Merchant integration
+
+
+
+
+
+
+ Use this information to link your Taler Merchant Backoffice account
+ with the current bank account. You can start by copying the values,
+ then go to your merchant backoffice service provider, login into
+ your account and look for the "import" button in the "bank account" section.
+
+
+
+
+ {payto !== undefined &&
+
+
+
+
+
+ {i18n.str`Account type`}
+
+
+
+
+
+ Method to use for wire transfer.
+
+
+ {((payto) => {
+ switch (payto.targetType) {
+ case "iban": {
+ return
+
+ {i18n.str`IBAN`}
+
+
+
+
+
+ International Bank Account Number.
+
+
+ }
+ case "x-taler-bank": {
+ return
+
+ {i18n.str`IBAN`}
+
+
+
+
+
+ International Bank Account Number.
+
+
+ }
+ case "bitcoin": {
+ return
+
+ {i18n.str`Address`}
+
+
+
+
+
+ International Bank Account Number.
+
+
+ }
+ }
+ })(payto)}
+
+
+
+ {i18n.str`Owner's name`}
+
+
+
+
+
+ Legal name of the person holding the account.
+
+
+
+
+ {i18n.str`Account info URL`}
+
+
+
+
+
+ From where the merchant can download information about incoming wire transfers to this account.
+
+
+
+
+
+
+ Cancel
+
+
accountLetter ?? ""}
+ class="flex text-center disabled:opacity-50 disabled:cursor-default cursor-pointer rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
+ Copy
+
+
+
+ }
+
+
+
);
}
diff --git a/packages/bank-ui/src/pages/admin/DownloadStats.tsx b/packages/bank-ui/src/pages/admin/DownloadStats.tsx
index 078435fe9..bef12c580 100644
--- a/packages/bank-ui/src/pages/admin/DownloadStats.tsx
+++ b/packages/bank-ui/src/pages/admin/DownloadStats.tsx
@@ -460,9 +460,9 @@ async function fetchAllStatus(
// await delay()
const previous = options.compareWithPrevious
? await api.getMonitor(token, {
- timeframe: frame.timeframe,
- which: frame.moment.previous,
- })
+ timeframe: frame.timeframe,
+ which: frame.moment.previous,
+ })
: undefined;
if (previous && previous.type === "fail" && options.endOnFirstFail) {
diff --git a/packages/bank-ui/src/pages/regional/ConversionConfig.tsx b/packages/bank-ui/src/pages/regional/ConversionConfig.tsx
index 8602580a0..014142e97 100644
--- a/packages/bank-ui/src/pages/regional/ConversionConfig.tsx
+++ b/packages/bank-ui/src/pages/regional/ConversionConfig.tsx
@@ -519,8 +519,8 @@ function useComponentState({
{cashoutCalc &&
- status.status === "ok" &&
- Amounts.cmp(status.result.amount, cashoutCalc.credit) <
+ status.status === "ok" &&
+ Amounts.cmp(status.result.amount, cashoutCalc.credit) <
0 ? (
{
- form.amount = value;
- updateForm(structuredClone(form));
- }
+ form.amount = value;
+ updateForm(structuredClone(form));
+ }
}
/>
{Amounts.isZero(sellFee) ||
- Amounts.isZero(calc.beforeFee) ? undefined : (
+ Amounts.isZero(calc.beforeFee) ? undefined : (
@@ -687,7 +689,7 @@ export function CreateCashout({
{/* channel, not shown if new cashout api */}
{!OLD_CASHOUT_API ? undefined : config.supported_tan_channels
- .length === 0 ? (
+ .length === 0 ? (
{
if (!resultAccount.body.contact_data?.phone) return;
diff --git a/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx b/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx
index 0f9f2d1b7..849da77aa 100644
--- a/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx
+++ b/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx
@@ -138,7 +138,7 @@ export function ShowCashoutDetails({ id, routeClose }: Props): VNode {
timestamp={AbsoluteTime.fromProtocolTimestamp(
result.body.creation_time,
)}
- // relative={Duration.fromSpec({ days: 1 })}
+ // relative={Duration.fromSpec({ days: 1 })}
/>
diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx b/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx
index b77c456e5..c01797e31 100644
--- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx
@@ -58,6 +58,7 @@ export const JustTwoBitcoinAccounts = tests.createExample(ReadyView, {
targetType: "bitcoin",
segwitAddrs: [],
isKnown: true,
+ address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
targetPath: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
params: {},
},
@@ -69,6 +70,7 @@ export const JustTwoBitcoinAccounts = tests.createExample(ReadyView, {
uri: {
targetType: "bitcoin",
segwitAddrs: [],
+ address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
isKnown: true,
targetPath: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
params: {},
@@ -138,6 +140,7 @@ export const WithAllTypeOfAccounts = tests.createExample(ReadyView, {
targetType: "bitcoin",
segwitAddrs: [],
isKnown: true,
+ address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
targetPath: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
params: {},
},
@@ -150,6 +153,7 @@ export const WithAllTypeOfAccounts = tests.createExample(ReadyView, {
targetType: "bitcoin",
segwitAddrs: [],
isKnown: true,
+ address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
targetPath: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
params: {},
},
--
cgit v1.2.3