commit 9ce574ae31377730d6edbd5b299cc1d0e85b3534
parent 600fe1a743730349724980baaca6cffc3ca742ec
Author: Sebastian <sebasjm@taler-systems.com>
Date: Tue, 30 Jun 2026 13:59:15 -0300
fix #11481
Diffstat:
2 files changed, 181 insertions(+), 74 deletions(-)
diff --git a/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx b/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx
@@ -20,6 +20,7 @@ import {
AmountString,
assertUnreachable,
encodeCrock,
+ KycAuthTransferInfo,
Paytos,
PaytoType,
QrCodeSpec,
@@ -83,9 +84,7 @@ function optionOrder(a: TransferOption, b: TransferOption) {
type OptionWithAccount = TransferOption & {
account: WithdrawalExchangeAccountDetails;
};
-export function BankDetailsByPaytoType({
- subject,
- amount,
+export function BankDetailsForWithdrawal({
accounts: unsortedAccounts,
}: BankDetailsProps): VNode {
const { i18n } = useTranslationContext();
@@ -97,26 +96,22 @@ export function BankDetailsByPaytoType({
const accounts = unsortedAccounts.sort(accountOrder);
const options = accounts.flatMap((account) =>
- account.transferOptions.sort(optionOrder).map(
- (op): OptionWithAccount => ({
- ...op,
- account,
- }),
- ),
- );
+ account.transferOptions.sort(optionOrder))
const selectedOption = options[index];
- const altCurrency = selectedOption.account.currencySpecification?.name;
+ // const altCurrency = selectedOption.account.currencySpecification?.name;
switch (selectedOption.type) {
case "ch-qr-bill":
case "payto": {
const payto = Result.unpack(Paytos.fromString(selectedOption.paytoUri));
+ const amount = Amounts.parseOrThrow(payto.params["amount"])
+ const subject = payto.params["subject"]
// make sure the payto has the right params
- payto.params["amount"] = altCurrency
- ? selectedOption.account.transferAmount!
- : Amounts.stringify(amount);
- payto.params["message"] = subject;
+ // payto.params["amount"] = altCurrency
+ // ? selectedOption.account.transferAmount!
+ // : Amounts.stringify(amount);
+ // payto.params["message"] = subject;
if (payto.targetType === PaytoType.Bitcoin) {
const min = segwitMinAmount(amount.currency);
@@ -131,7 +126,6 @@ export function BankDetailsByPaytoType({
accounts={options}
updateIndex={setIndex}
currentIndex={index}
- defaultCurrency={amount.currency}
>
<p>
<i18n.Translate>
@@ -185,7 +179,6 @@ export function BankDetailsByPaytoType({
accounts={options}
updateIndex={setIndex}
currentIndex={index}
- defaultCurrency={amount.currency}
>
<p>
<i18n.Translate>
@@ -221,7 +214,6 @@ export function BankDetailsByPaytoType({
accounts={options}
updateIndex={setIndex}
currentIndex={index}
- defaultCurrency={amount.currency}
>
<IBANAccountInfoTable
payto={payto}
@@ -243,7 +235,6 @@ export function BankDetailsByPaytoType({
accounts={options}
updateIndex={setIndex}
currentIndex={index}
- defaultCurrency={amount.currency}
>
<i18n.Translate>
The selected option is not currently supported. URI:{" "}
@@ -257,6 +248,170 @@ export function BankDetailsByPaytoType({
}
}
+export function BankDetailsForKycAuth({
+ info
+}: { info: KycAuthTransferInfo }): VNode {
+ const { i18n } = useTranslationContext();
+ const [index, setIndex] = useState(0);
+
+ const { transferOptions: unsortedOptions } = info
+
+ if (!unsortedOptions.length) {
+ return <div>the exchange account list is empty</div>;
+ }
+
+ const options = unsortedOptions.sort(optionOrder)
+
+ const selectedOption = options[index];
+
+ switch (selectedOption.type) {
+ case "ch-qr-bill":
+ case "payto": {
+ const payto = Result.unpack(Paytos.fromString(selectedOption.paytoUri));
+ const amount = Amounts.parseOrThrow(payto.params["amount"])
+ const subject = payto.params["subject"]
+ // make sure the payto has the right params
+ // payto.params["amount"] = altCurrency
+ // ? selectedOption.account.transferAmount!
+ // : Amounts.stringify(amount);
+ // payto.params["message"] = subject;
+
+ // if (payto.targetType === PaytoType.Bitcoin) {
+ // const min = segwitMinAmount(amount.currency);
+ // const addrs = payto.segwitAddrs.map(
+ // (a) => `${a} ${Amounts.stringifyValue(min)}`,
+ // );
+ // addrs.unshift(`${payto.address} ${Amounts.stringifyValue(amount)}`);
+ // const copyContent = addrs.join("\n");
+ // return (
+ // <Frame
+ // title={i18n.str`Bitcoin transfer details`}
+ // accounts={options}
+ // updateIndex={setIndex}
+ // currentIndex={index}
+ // defaultCurrency={amount.currency}
+ // >
+ // <p>
+ // <i18n.Translate>
+ // The exchange need a transaction with 3 output, one output is the
+ // exchange account and the other two are segwit fake address for
+ // metadata with an minimum amount.
+ // </i18n.Translate>
+ // </p>
+
+ // <p>
+ // <i18n.Translate>
+ // In bitcoincore wallet use 'Add Recipient' button to
+ // add two additional recipient and copy addresses and amounts
+ // </i18n.Translate>
+ // </p>
+ // <table>
+ // <tr>
+ // <td>
+ // <div>
+ // {payto.address} <Amount value={amount} hideCurrency /> BTC
+ // </div>
+ // {payto.segwitAddrs.map((addr, i) => (
+ // <div key={i}>
+ // {addr} <Amount value={min} hideCurrency /> BTC
+ // </div>
+ // ))}
+ // </td>
+ // <td></td>
+ // <td>
+ // <CopyButton getContent={() => copyContent} />
+ // </td>
+ // </tr>
+ // </table>
+ // <p>
+ // <i18n.Translate>
+ // Make sure the amount show{" "}
+ // {Amounts.stringifyValue(Amounts.sum([amount, min, min]).amount)}{" "}
+ // BTC, else you have to change the base unit to BTC
+ // </i18n.Translate>
+ // </p>
+ // </Frame>
+ // );
+ // }
+
+ // if (payto.targetType === PaytoType.Ethereum) {
+ // const min = segwitMinAmount(amount.currency);
+ // const copyContent = `${payto.address} ${Amounts.stringifyValue(amount)}`;
+ // return (
+ // <Frame
+ // title={i18n.str`Ethereum transfer details`}
+ // accounts={options}
+ // updateIndex={setIndex}
+ // currentIndex={index}
+ // defaultCurrency={amount.currency}
+ // >
+ // <p>
+ // <i18n.Translate>
+ // You need to wire to the service provider account.
+ // </i18n.Translate>
+ // </p>
+
+ // <table>
+ // <tr>
+ // <td>
+ // <div>
+ // {payto.address} <Amount value={amount} hideCurrency /> ETH
+ // </div>
+ // </td>
+ // <td></td>
+ // <td>
+ // <CopyButton getContent={() => copyContent} />
+ // </td>
+ // </tr>
+ // </table>
+ // <p>
+ // <i18n.Translate>
+ // Make sure the amount show {Amounts.stringifyValue(amount)} ETH
+ // </i18n.Translate>
+ // </p>
+ // </Frame>
+ // );
+ // }
+
+ return (
+ <Frame
+ title={i18n.str`Bank transfer details`}
+ accounts={options}
+ updateIndex={setIndex}
+ currentIndex={index}
+ >
+ <IBANAccountInfoTable
+ payto={payto}
+ qrCodes={selectedOption.qrCodes}
+ refCode={
+ selectedOption.type === "ch-qr-bill"
+ ? selectedOption.qrReferenceNumber
+ : undefined
+ }
+ subject={subject}
+ />
+ </Frame>
+ );
+ }
+ case "uri": {
+ return (
+ <Frame
+ title={i18n.str`URI details`}
+ accounts={options}
+ updateIndex={setIndex}
+ currentIndex={index}
+ >
+ <i18n.Translate>
+ The selected option is not currently supported. URI:{" "}
+ {selectedOption.uri}
+ </i18n.Translate>
+ </Frame>
+ );
+ }
+ default:
+ assertUnreachable(selectedOption);
+ }
+}
export function IBANAccountInfoTable({
payto,
qrCodes,
@@ -321,7 +476,6 @@ export function IBANAccountInfoTable({
);
case "spc":
return <QR_SwissBank text={q.qrContent} />;
-
default:
assertUnreachable(q.type);
}
@@ -621,7 +775,6 @@ function Frame({
title,
children,
accounts,
- defaultCurrency,
currentIndex,
updateIndex,
}: {
@@ -629,8 +782,7 @@ function Frame({
children: ComponentChildren;
currentIndex: number;
updateIndex: (idx: number) => void;
- defaultCurrency: string;
- accounts: OptionWithAccount[];
+ accounts: TransferOption[];
}): VNode {
const { i18n } = useTranslationContext();
return (
@@ -656,8 +808,6 @@ function Frame({
{accounts.length > 1 ? (
<Fragment>
{accounts.map((ac, acIdx) => {
- // const accountLabel =
- // ac.account.bankLabel ?? i18n.str`Option #${acIdx + 1}`;
const desc = ac.type === "ch-qr-bill" ? i18n.str`Swiss Bill` : i18n.str`Wire transfer`
return (
<Button
@@ -667,7 +817,7 @@ function Frame({
updateIndex(acIdx);
}}
>
- {ac.account.currencySpecification?.name ?? defaultCurrency} - {desc}
+ {acIdx+1}) {desc}
</Button>
);
})}
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
@@ -26,7 +26,6 @@ import {
NotificationType,
OrderShortInfo,
parsePaytoUri,
- Paytos,
PaytoUri,
Result,
ScopeInfo,
@@ -44,7 +43,7 @@ import {
TransactionType,
TransactionWithdrawal,
TranslatedString,
- WithdrawalType,
+ WithdrawalType
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { QR_Taler, useTranslationContext } from "@gnu-taler/web-util/browser";
@@ -52,10 +51,10 @@ import { isPast } from "date-fns";
import { ComponentChildren, Fragment, h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks";
import { Amount } from "../components/Amount.js";
-import { BankDetailsByPaytoType, IBANAccountInfoTable } from "../components/BankDetailsByPaytoType.js";
+import { BankDetailsForKycAuth, BankDetailsForWithdrawal } from "../components/BankDetailsByPaytoType.js";
import { AlertView, ErrorAlertView } from "../components/CurrentAlerts.js";
import { Loading } from "../components/Loading.js";
-import { Kind, Part, PartPayto } from "../components/Part.js";
+import { Kind, Part } from "../components/Part.js";
import { ShowFullContractTermPopup } from "../components/ShowFullContractTermPopup.js";
import {
CenteredDialog,
@@ -534,7 +533,7 @@ export function TransactionView({
</span>
)}
</InfoBox>
- <BankDetailsByPaytoType
+ <BankDetailsForWithdrawal
amount={raw}
accounts={
transaction.withdrawalDetails.exchangeCreditAccountDetails ?? []
@@ -771,50 +770,8 @@ export function TransactionView({
>
{!payto ? transaction.targetPaytoUri : <NicePayto payto={payto} />}
</Header>
- {/* {payto && <PartPayto payto={payto} kind="neutral" />} */}
- {/* <BankDetailsByPaytoType
- amount={raw}
- accounts={
- transaction.kycAuthTransferInfo.exchangeCreditAccountDetails ?? []
- }
- subject={transaction.kycAuthTransferInfo.accountPub}
- /> */}
- {/* <pre>
- {JSON.stringify({ info }, undefined, 2)}
- </pre> */}
-
{!info ? undefined :
- <section
- style={{
- textAlign: "left",
- border: "solid 1px black",
- padding: 8,
- borderRadius: 4,
- }}
- >
- <div
- style={{
- display: "flex",
- width: "100%",
- justifyContent: "space-between",
- }}
- >
- <p style={{ marginTop: 0 }}><i18n.Translate>Bank transfer details</i18n.Translate></p>
- <div></div>
- </div>
- {
- info.transferOptions.map(d => {
- switch (d.type) {
- case "payto":
- return <IBANAccountInfoTable payto={Result.unpack(Paytos.fromString(d.paytoUri))} qrCodes={d.qrCodes} subject={info.accountPub} />
- case "uri":
- case "ch-qr-bill":
- return <i18n.Translate>Transfer option type "{d.type}"" is not supported by this wallet</i18n.Translate>
- }
- })
-
- }
- </section>
+ <BankDetailsForKycAuth info={info}/>
}
<Part
title={i18n.str`Details`}