View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0012087 | Taler | wallet (WebExtension) | public | 2026-11-11 01:41 | 2026-11-11 01:41 |
| Reporter | bot-cg [agent] | Assigned To | Resolution deadline | ||
| Implementer | Reviewer | ||||
| Release signed by | Deployed by | ||||
| Verifier | Communicator | CM_7 | |||
| Data protection authority notification required | No | ||||
| CSIRT notification required | No | ||||
| Estimated effort (hours) | Actual effort (hours) | 0 | |||
| Fast-track | No | ||||
| Work package | none | ||||
| Priority | normal | Severity | minor | Reproducibility | have not tried |
| Status | new | Resolution | open | ||
| Summary | 0012087: WebExtension: editing a saved bank account only offers the raw payto:// URI -- Android and iOS reopen the structured form (patch attached) | ||||
| Description | Settings -> Bank accounts -> "Edit" in the web wallet does not reopen the account in the form used to add it. It always switches to the "Advanced payto URI" method and shows a single monospace text box with the stored URI (e.g. payto://x-taler-bank/sandcastle/alice?receiver-name=Alice%20Example) plus Label and Currencies; the account-type chooser is hidden. To change the holder or the account number the user has to edit a percent-encoded URI; removing "?receiver-name=…" is accepted and the account silently loses its holder, and a typo only yields "Enter a valid supported payto URI." Android and iOS open the same account in their structured form, pre-filled. Screenshots (demo backend, account added through the web form as "Taler-enabled bank", holder Alice Example, bank sandcastle, account alice): - before-web-1-list.png: the list; note also that accounts the wallet learned from withdrawals have no label, so their title is the raw payto URI. - before-web-2-edit.png: Edit -> "Payto URI" box only. - before-web-3-holder-removed.png: after deleting receiver-name and saving, the account has no holder. - before-android-1-edit.png, before-ios-1-edit.png (reference): holder, bank/IBAN and account fields pre-filled. - after-web-2-edit.png: with the patch, Edit shows Account holder name / Bank / Account name / Label pre-filled. - after-web-3-saved.png: holder changed to "Alice Example-Smith" and saved through the guided form. Code (taler-typescript-core origin/master bf2e571a2, packages/wallet-webui/src/): - screens/BankAccountsScreen.tsx:75-77 and 107-116: method forced to "advanced" whenever props.editing is set - screens/BankAccountsScreen.tsx:311-329: account-type select only when not editing - screens/BankAccountsScreen.tsx:477-492: the "Payto URI" input - routes/management-model.ts:240-241: "advanced" passes the URI through; routes/ManagementRoutes.tsx:580-632: only the guided IBAN path validates and converts For comparison: Android accounts/AddAccountComposable.kt:93-118 (pre-fills from the parsed payto), iOS Views/Settings/Bank/BankEditView.swift:81-101. Patch (attached, web-bank-account-structured-edit.patch, BankAccountsScreen.tsx only): a helper parses the saved URI with Paytos.fromString() and pre-fills the guided form when editing -- IBAN: holder, IBAN, town, postal code; x-taler-bank: holder, bank, account; bitcoin: address. It falls back to the advanced payto field when the type is not among the offered methods, when there is no holder, or when the bank host is not one of the exchange's hosts (the bank field is a select over those). Saving goes through the existing guided paths (IBAN conversion/validation, constructPayto). No new strings. Verification: Chrome extension build; after-web-2-edit.png / after-web-3-saved.png. pnpm typecheck: same 29 pre-existing errors in test/*.test.tsx with and without the patch, none in the touched file; prettier clean. Related: 0012053 (focus on Edit; the form it opens is the one changed here). Assisted by LLM | ||||
| Steps To Reproduce | 1. Settings -> Bank accounts -> Add bank account: "Taler-enabled bank", holder, bank, account name, label -> Add account. 2. Press "Edit" on that account: only a "Payto URI" field is offered. | ||||
| Tags | No tags attached. | ||||
| Attached Files | web-bank-account-structured-edit.patch (4,078 bytes)
diff --git a/packages/wallet-webui/src/screens/BankAccountsScreen.tsx b/packages/wallet-webui/src/screens/BankAccountsScreen.tsx
index 051179b24..923aa87d1 100644
--- a/packages/wallet-webui/src/screens/BankAccountsScreen.tsx
+++ b/packages/wallet-webui/src/screens/BankAccountsScreen.tsx
@@ -1,4 +1,5 @@
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
+import { Paytos, PaytoType, Result } from "@gnu-taler/taler-util";
import { Button } from "../ui/Button.js";
import { Card } from "../ui/Card.js";
import { ErrorCard } from "../ui/ErrorCard.js";
@@ -47,6 +48,79 @@ function supportedMethod(
return value === "iban" || value === "x-taler-bank" || value === "bitcoin";
}
+interface BankAccountFields {
+ method: GuidedMethod;
+ receiverName: string;
+ receiverTown: string;
+ receiverPostalCode: string;
+ accountField: string;
+ bankHost: string;
+ bankAccount: string;
+ bitcoinAddress: string;
+}
+
+/**
+ * The form fields for a saved account, so that editing uses the same guided
+ * form as adding; a URI that the guided methods cannot represent stays raw.
+ */
+function bankAccountFields(
+ account: BankAccountView | undefined,
+ guidedMethods: GuidedMethod[],
+ wireTypes: BankAccountWireTypeView[] | undefined,
+): BankAccountFields {
+ const fields: BankAccountFields = {
+ method: account ? "advanced" : (guidedMethods[0] ?? "advanced"),
+ receiverName: "",
+ receiverTown: "",
+ receiverPostalCode: "",
+ accountField: "",
+ bankHost: "",
+ bankAccount: "",
+ bitcoinAddress: "",
+ };
+ if (!account) return fields;
+ const parsed = Paytos.fromString(account.paytoUri);
+ if (Result.isError(parsed)) return fields;
+ const payto = parsed.value;
+ const holder = Paytos.getAccountHolder(payto) ?? "";
+ switch (payto.targetType) {
+ case PaytoType.IBAN:
+ if (!guidedMethods.includes("iban") || !holder) return fields;
+ return {
+ ...fields,
+ method: "iban",
+ receiverName: holder,
+ accountField: payto.iban,
+ receiverTown: payto.params["receiver-town"] ?? "",
+ receiverPostalCode: payto.params["receiver-postal-code"] ?? "",
+ };
+ case PaytoType.TalerBank: {
+ const hosts =
+ wireTypes?.find((entry) => entry.paymentTargetType === "x-taler-bank")
+ ?.talerBankHostnames ?? [];
+ // the bank field is a choice among these hosts when there are any
+ if (
+ !guidedMethods.includes("x-taler-bank") ||
+ !holder ||
+ (hosts.length > 0 && !hosts.includes(payto.host))
+ )
+ return fields;
+ return {
+ ...fields,
+ method: "x-taler-bank",
+ receiverName: holder,
+ bankHost: payto.host,
+ bankAccount: payto.account,
+ };
+ }
+ case PaytoType.Bitcoin:
+ if (!guidedMethods.includes("bitcoin")) return fields;
+ return { ...fields, method: "bitcoin", bitcoinAddress: payto.address };
+ default:
+ return fields;
+ }
+}
+
export function BankAccountsScreen(props: {
accounts?: BankAccountView[];
wireTypes?: BankAccountWireTypeView[];
@@ -112,8 +186,20 @@ export function BankAccountsScreen(props: {
setLabel(props.editing?.label ?? "");
setCurrencies(props.editing?.currencies.join(", ") ?? "");
setPaytoUri(props.editing?.paytoUri ?? "");
- setMethod(props.editing ? "advanced" : (guidedMethods[0] ?? "advanced"));
- }, [guidedMethods, props.editing]);
+ const fields = bankAccountFields(
+ props.editing,
+ guidedMethods,
+ props.wireTypes,
+ );
+ setMethod(fields.method);
+ setReceiverName(fields.receiverName);
+ setReceiverTown(fields.receiverTown);
+ setReceiverPostalCode(fields.receiverPostalCode);
+ setAccountField(fields.accountField);
+ setBankHost(fields.bankHost);
+ setBankAccount(fields.bankAccount);
+ setBitcoinAddress(fields.bitcoinAddress);
+ }, [guidedMethods, props.editing, props.wireTypes]);
const wireType = props.wireTypes?.find(
(entry) => entry.paymentTargetType === method,
);
| ||||
| related to | 0012053 | new | Wallet: Bank accounts 'Edit' / 'Add bank account' leave focus on the button; the opened form can be off-screen |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-11-11 01:41 | bot-cg | New Issue | |
| 2026-11-11 01:41 | bot-cg | Relationship added | related to 0012053 |
| 2026-11-11 01:41 | bot-cg | File Added: before-web-1-list.png | |
| 2026-11-11 01:41 | bot-cg | File Added: before-web-2-edit.png | |
| 2026-11-11 01:41 | bot-cg | File Added: before-web-3-holder-removed.png | |
| 2026-11-11 01:41 | bot-cg | File Added: before-android-1-edit.png | |
| 2026-11-11 01:41 | bot-cg | File Added: before-ios-1-edit.png | |
| 2026-11-11 01:41 | bot-cg | File Added: after-web-2-edit.png | |
| 2026-11-11 01:41 | bot-cg | File Added: after-web-3-saved.png | |
| 2026-11-11 01:41 | bot-cg | File Added: web-bank-account-structured-edit.patch |