gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated (43a543b41 -> dc002f99a)


From: gnunet
Subject: [taler-wallet-core] branch master updated (43a543b41 -> dc002f99a)
Date: Thu, 22 Dec 2022 22:42:31 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a change to branch master
in repository wallet-core.

    from 43a543b41 fix: reload before fetch. input type=submit reload the spa
     new 9fb0e7d0b prevent form submit
     new a221ec6b7 fix unhandled input
     new 6fd775632 also offer temporary ext+taler
     new 5c84c3273 pretty
     new dc002f99a support for ext+taler:// while taler:// is not yet allowed 
as scheme

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../src/components/Transactions/state.ts           |   53 +-
 .../src/components/Transactions/test.ts            |  224 +--
 .../demobank-ui/src/components/index.examples.ts   |    2 +-
 packages/demobank-ui/src/endpoints.ts              |    8 +-
 packages/demobank-ui/src/hooks/index.ts            |    5 +-
 packages/demobank-ui/src/i18n/strings.ts           | 1493 ++++++--------------
 packages/demobank-ui/src/pages/LoginForm.tsx       |   16 +-
 .../src/pages/PaytoWireTransferForm.tsx            |   16 +-
 packages/demobank-ui/src/pages/QrCodeSection.tsx   |   15 +-
 .../demobank-ui/src/pages/RegistrationPage.tsx     |   15 +-
 .../demobank-ui/src/pages/WalletWithdrawForm.tsx   |   14 +-
 .../src/pages/WithdrawalConfirmationQuestion.tsx   |   42 +-
 packages/demobank-ui/src/stories.test.ts           |   10 +-
 .../taler-wallet-webextension/manifest-v2.json     |    7 +
 .../taler-wallet-webextension/manifest-v3.json     |   12 +
 .../src/cta/Withdraw/state.ts                      |    7 +-
 .../src/platform/chrome.ts                         |    5 +-
 .../src/wallet/DeveloperPage.tsx                   |   60 +-
 .../taler-wallet-webextension/src/wxBackend.ts     |    5 +-
 19 files changed, 759 insertions(+), 1250 deletions(-)

diff --git a/packages/demobank-ui/src/components/Transactions/state.ts 
b/packages/demobank-ui/src/components/Transactions/state.ts
index 5d613c5d0..b17986e48 100644
--- a/packages/demobank-ui/src/components/Transactions/state.ts
+++ b/packages/demobank-ui/src/components/Transactions/state.ts
@@ -20,7 +20,11 @@ import { useEffect } from "preact/hooks";
 import useSWR from "swr";
 import { Props, State } from "./index.js";
 
-export function useComponentState({ accountLabel, pageNumber, balanceValue }: 
Props): State {
+export function useComponentState({
+  accountLabel,
+  pageNumber,
+  balanceValue,
+}: Props): State {
   const { data, error, mutate } = useSWR(
     `access-api/accounts/${accountLabel}/transactions?page=${pageNumber}`,
   );
@@ -39,40 +43,41 @@ export function useComponentState({ accountLabel, 
pageNumber, balanceValue }: Pr
           error: {
             hasError: true,
             operational: false,
-            message: `Transactions page ${pageNumber} was not found.`
-          }
-        }
+            message: `Transactions page ${pageNumber} was not found.`,
+          },
+        };
       case 401:
         return {
           status: "loading-error",
           error: {
             hasError: true,
             operational: false,
-            message: "Wrong credentials given."
-          }
-        }
+            message: "Wrong credentials given.",
+          },
+        };
       default:
         return {
           status: "loading-error",
           error: {
             hasError: true,
             operational: false,
-            message: `Transaction page ${pageNumber} could not be retrieved.`
-          } as any
-        }
+            message: `Transaction page ${pageNumber} could not be retrieved.`,
+          } as any,
+        };
     }
   }
 
   if (!data) {
     return {
       status: "loading",
-      error: undefined
-    }
+      error: undefined,
+    };
   }
 
-
   const transactions = data.transactions.map((item: unknown) => {
-    if (!item || typeof item !== "object" ||
+    if (
+      !item ||
+      typeof item !== "object" ||
       !("direction" in item) ||
       !("creditorIban" in item) ||
       !("debtorIban" in item) ||
@@ -86,12 +91,12 @@ export function useComponentState({ accountLabel, 
pageNumber, balanceValue }: Pr
     }
     const anyItem = item as any;
     if (
-      !(typeof anyItem.creditorIban === 'string') ||
-      !(typeof anyItem.debtorIban === 'string') ||
-      !(typeof anyItem.date === 'string') ||
-      !(typeof anyItem.subject === 'string') ||
-      !(typeof anyItem.currency === 'string') ||
-      !(typeof anyItem.amount === 'string')
+      !(typeof anyItem.creditorIban === "string") ||
+      !(typeof anyItem.debtorIban === "string") ||
+      !(typeof anyItem.date === "string") ||
+      !(typeof anyItem.subject === "string") ||
+      !(typeof anyItem.currency === "string") ||
+      !(typeof anyItem.amount === "string")
     ) {
       return;
     }
@@ -109,11 +114,11 @@ export function useComponentState({ accountLabel, 
pageNumber, balanceValue }: Pr
         ? `${dateParse[3]}/${dateParse[2]} ${dateParse[1]}`
         : undefined;
 
-    const date = parse(dateStr ?? "", "dd/MM yyyy", new Date())
+    const date = parse(dateStr ?? "", "dd/MM yyyy", new Date());
 
     const when: AbsoluteTime = {
-      t_ms: date.getTime()
-    }
+      t_ms: date.getTime(),
+    };
     const amount = Amounts.parse(`${anyItem.currency}:${anyItem.amount}`);
     const subject = anyItem.subject;
     return {
@@ -122,7 +127,7 @@ export function useComponentState({ accountLabel, 
pageNumber, balanceValue }: Pr
       when,
       amount,
       subject,
-    }
+    };
   });
 
   return {
diff --git a/packages/demobank-ui/src/components/Transactions/test.ts 
b/packages/demobank-ui/src/components/Transactions/test.ts
index b746f6bb7..21a0eefbb 100644
--- a/packages/demobank-ui/src/components/Transactions/test.ts
+++ b/packages/demobank-ui/src/components/Transactions/test.ts
@@ -26,149 +26,157 @@ import { TRANSACTION_API_EXAMPLE } from 
"../../endpoints.js";
 import { Props } from "./index.js";
 import { useComponentState } from "./state.js";
 
-
 describe("Transaction states", () => {
-
   it("should query backend and render transactions", async () => {
-
     const env = new SwrMockEnvironment();
 
     const props: Props = {
       accountLabel: "myAccount",
-      pageNumber: 0
-    }
+      pageNumber: 0,
+    };
 
     env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_FIRST_PAGE, {
       response: {
-        "transactions": [
+        transactions: [
           {
-            "creditorIban": "DE159593",
-            "creditorBic": "SANDBOXX",
-            "creditorName": "exchange company",
-            "debtorIban": "DE118695",
-            "debtorBic": "SANDBOXX",
-            "debtorName": "Name unknown",
-            "amount": "1",
-            "currency": "KUDOS",
-            "subject": "Taler Withdrawal 
N588V8XE9TR49HKAXFQ20P0EQ0EYW2AC9NNANV8ZP5P59N6N0410",
-            "date": "2022-12-12Z",
-            "uid": "8PPFR9EM",
-            "direction": "DBIT",
-            "pmtInfId": null,
-            "msgId": null
+            creditorIban: "DE159593",
+            creditorBic: "SANDBOXX",
+            creditorName: "exchange company",
+            debtorIban: "DE118695",
+            debtorBic: "SANDBOXX",
+            debtorName: "Name unknown",
+            amount: "1",
+            currency: "KUDOS",
+            subject:
+              "Taler Withdrawal 
N588V8XE9TR49HKAXFQ20P0EQ0EYW2AC9NNANV8ZP5P59N6N0410",
+            date: "2022-12-12Z",
+            uid: "8PPFR9EM",
+            direction: "DBIT",
+            pmtInfId: null,
+            msgId: null,
           },
           {
-            "creditorIban": "DE159593",
-            "creditorBic": "SANDBOXX",
-            "creditorName": "exchange company",
-            "debtorIban": "DE118695",
-            "debtorBic": "SANDBOXX",
-            "debtorName": "Name unknown",
-            "amount": "5.00",
-            "currency": "KUDOS",
-            "subject": "HNEWWT679TQC5P1BVXJS48FX9NW18FWM6PTK2N80Z8GVT0ACGNK0",
-            "date": "2022-12-07Z",
-            "uid": "7FZJC3RJ",
-            "direction": "DBIT",
-            "pmtInfId": null,
-            "msgId": null
+            creditorIban: "DE159593",
+            creditorBic: "SANDBOXX",
+            creditorName: "exchange company",
+            debtorIban: "DE118695",
+            debtorBic: "SANDBOXX",
+            debtorName: "Name unknown",
+            amount: "5.00",
+            currency: "KUDOS",
+            subject: "HNEWWT679TQC5P1BVXJS48FX9NW18FWM6PTK2N80Z8GVT0ACGNK0",
+            date: "2022-12-07Z",
+            uid: "7FZJC3RJ",
+            direction: "DBIT",
+            pmtInfId: null,
+            msgId: null,
           },
           {
-            "creditorIban": "DE118695",
-            "creditorBic": "SANDBOXX",
-            "creditorName": "Name unknown",
-            "debtorIban": "DE579516",
-            "debtorBic": "SANDBOXX",
-            "debtorName": "The Bank",
-            "amount": "100",
-            "currency": "KUDOS",
-            "subject": "Sign-up bonus",
-            "date": "2022-12-07Z",
-            "uid": "I31A06J8",
-            "direction": "CRDT",
-            "pmtInfId": null,
-            "msgId": null
-          }
-        ]
-      }
-    });
-
-    const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, 
props, [
-      ({ status, error }) => {
-
-        expect(status).equals("loading");
-        expect(error).undefined;
-      },
-      ({ status, error }) => {
-
-        expect(status).equals("ready");
-        expect(error).undefined;
+            creditorIban: "DE118695",
+            creditorBic: "SANDBOXX",
+            creditorName: "Name unknown",
+            debtorIban: "DE579516",
+            debtorBic: "SANDBOXX",
+            debtorName: "The Bank",
+            amount: "100",
+            currency: "KUDOS",
+            subject: "Sign-up bonus",
+            date: "2022-12-07Z",
+            uid: "I31A06J8",
+            direction: "CRDT",
+            pmtInfId: null,
+            msgId: null,
+          },
+        ],
       },
-    ], env.buildTestingContext())
-
-    expect(hookBehavior).deep.eq({ result: "ok" })
+    });
 
-    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" })
+    const hookBehavior = await tests.hookBehaveLikeThis(
+      useComponentState,
+      props,
+      [
+        ({ status, error }) => {
+          expect(status).equals("loading");
+          expect(error).undefined;
+        },
+        ({ status, error }) => {
+          expect(status).equals("ready");
+          expect(error).undefined;
+        },
+      ],
+      env.buildTestingContext(),
+    );
+
+    expect(hookBehavior).deep.eq({ result: "ok" });
+
+    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" });
   });
 
   it("should show error message on not found", async () => {
-
     const env = new SwrMockEnvironment();
 
     const props: Props = {
       accountLabel: "myAccount",
-      pageNumber: 0
-    }
+      pageNumber: 0,
+    };
 
     env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_NOT_FOUND, {});
 
-    const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, 
props, [
-      ({ status, error }) => {
-        expect(status).equals("loading");
-        expect(error).undefined;
-      },
-      ({ status, error }) => {
-        expect(status).equals("loading-error");
-        expect(error).deep.eq({
-          hasError: true,
-          operational: false,
-          message: "Transactions page 0 was not found."
-        });
-      },
-    ], env.buildTestingContext())
-
-    expect(hookBehavior).deep.eq({ result: "ok" })
-    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" })
+    const hookBehavior = await tests.hookBehaveLikeThis(
+      useComponentState,
+      props,
+      [
+        ({ status, error }) => {
+          expect(status).equals("loading");
+          expect(error).undefined;
+        },
+        ({ status, error }) => {
+          expect(status).equals("loading-error");
+          expect(error).deep.eq({
+            hasError: true,
+            operational: false,
+            message: "Transactions page 0 was not found.",
+          });
+        },
+      ],
+      env.buildTestingContext(),
+    );
+
+    expect(hookBehavior).deep.eq({ result: "ok" });
+    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" });
   });
 
   it("should show error message on server error", async () => {
-
     const env = new SwrMockEnvironment(false);
 
     const props: Props = {
       accountLabel: "myAccount",
-      pageNumber: 0
-    }
+      pageNumber: 0,
+    };
 
     env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_ERROR, {});
 
-    const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, 
props, [
-      ({ status, error }) => {
-        expect(status).equals("loading");
-        expect(error).undefined;
-      },
-      ({ status, error }) => {
-        expect(status).equals("loading-error");
-        expect(error).deep.equal({
-          hasError: true,
-          operational: false,
-          message: "Transaction page 0 could not be retrieved."
-        });
-      },
-    ], env.buildTestingContext())
-
-    expect(hookBehavior).deep.eq({ result: "ok" })
-    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" })
+    const hookBehavior = await tests.hookBehaveLikeThis(
+      useComponentState,
+      props,
+      [
+        ({ status, error }) => {
+          expect(status).equals("loading");
+          expect(error).undefined;
+        },
+        ({ status, error }) => {
+          expect(status).equals("loading-error");
+          expect(error).deep.equal({
+            hasError: true,
+            operational: false,
+            message: "Transaction page 0 could not be retrieved.",
+          });
+        },
+      ],
+      env.buildTestingContext(),
+    );
+
+    expect(hookBehavior).deep.eq({ result: "ok" });
+    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" });
   });
 });
-
diff --git a/packages/demobank-ui/src/components/index.examples.ts 
b/packages/demobank-ui/src/components/index.examples.ts
index a741b413d..348d5c653 100644
--- a/packages/demobank-ui/src/components/index.examples.ts
+++ b/packages/demobank-ui/src/components/index.examples.ts
@@ -14,4 +14,4 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-export * as tx from "./Transactions/stories.js";
\ No newline at end of file
+export * as tx from "./Transactions/stories.js";
diff --git a/packages/demobank-ui/src/endpoints.ts 
b/packages/demobank-ui/src/endpoints.ts
index 0130e94f8..e20525ae2 100644
--- a/packages/demobank-ui/src/endpoints.ts
+++ b/packages/demobank-ui/src/endpoints.ts
@@ -27,11 +27,11 @@ export const TRANSACTION_API_EXAMPLE = {
   LIST_ERROR: {
     method: "get" as const,
     url: "access-api/accounts/myAccount/transactions?page=0",
-    code: 500
+    code: 500,
   },
   LIST_NOT_FOUND: {
     method: "get" as const,
     url: "access-api/accounts/myAccount/transactions?page=0",
-    code: 404
-  }
-}
\ No newline at end of file
+    code: 404,
+  },
+};
diff --git a/packages/demobank-ui/src/hooks/index.ts 
b/packages/demobank-ui/src/hooks/index.ts
index c582a5c63..263b53e1d 100644
--- a/packages/demobank-ui/src/hooks/index.ts
+++ b/packages/demobank-ui/src/hooks/index.ts
@@ -20,7 +20,10 @@
  */
 
 import { StateUpdater } from "preact/hooks";
-import { useLocalStorage, useNotNullLocalStorage } from 
"@gnu-taler/web-util/lib/index.browser";
+import {
+  useLocalStorage,
+  useNotNullLocalStorage,
+} from "@gnu-taler/web-util/lib/index.browser";
 export type ValueOrFunction<T> = T | ((p: T) => T);
 
 const calculateRootPath = () => {
diff --git a/packages/demobank-ui/src/i18n/strings.ts 
b/packages/demobank-ui/src/i18n/strings.ts
index 3aabbc460..a779bbc49 100644
--- a/packages/demobank-ui/src/i18n/strings.ts
+++ b/packages/demobank-ui/src/i18n/strings.ts
@@ -15,1149 +15,496 @@
  */
 
 /*eslint quote-props: ["error", "consistent"]*/
-export const strings: {[s: string]: any} = {};
+export const strings: { [s: string]: any } = {};
 
-strings['de'] = {
-  "domain": "messages",
-  "locale_data": {
-    "messages": {
+strings["de"] = {
+  domain: "messages",
+  locale_data: {
+    messages: {
       "": {
-        "domain": "messages",
-        "plural_forms": "nplurals=2; plural=(n != 1);",
-        "lang": "de"
+        domain: "messages",
+        plural_forms: "nplurals=2; plural=(n != 1);",
+        lang: "de",
       },
-      "Logout": [
-        ""
-      ],
-      "Skip to main content": [
-        ""
-      ],
-      "This part of the demo shows how a bank that supports Taler directly 
would work. In addition to using your own bank account, you can also see the 
transaction history of some %1$s.": [
-        ""
-      ],
-      "Taler logo": [
-        ""
-      ],
-      "Missing username": [
-        ""
-      ],
-      "Missing password": [
-        ""
-      ],
-      "Please login!": [
-        ""
-      ],
-      "Username:": [
-        ""
-      ],
-      "Password:": [
-        ""
-      ],
-      "Login": [
-        ""
-      ],
-      "Register": [
-        ""
-      ],
-      "Missing IBAN": [
-        ""
-      ],
-      "IBAN should have just uppercased letters and numbers": [
-        ""
-      ],
-      "Missing subject": [
-        ""
-      ],
-      "Missing amount": [
-        ""
-      ],
-      "Amount is not valid": [
-        ""
-      ],
-      "Should be greater than 0": [
-        ""
-      ],
-      "Receiver IBAN:": [
-        ""
-      ],
-      "Transfer subject:": [
-        ""
-      ],
-      "Amount:": [
-        ""
-      ],
-      "Field(s) missing.": [
-        ""
-      ],
-      "Want to try the raw payto://-format?": [
-        ""
-      ],
-      "Missing payto address": [
-        ""
-      ],
-      "Payto does not follow the pattern": [
-        ""
-      ],
-      "Transfer money to account identified by payto:// URI:": [
-        ""
-      ],
-      "payto URI:": [
-        ""
-      ],
-      "payto address": [
-        ""
-      ],
-      "Send": [
-        ""
-      ],
-      "Use wire-transfer form?": [
-        ""
-      ],
-      "No credentials found.": [
-        ""
-      ],
-      "Could not create the wire transfer": [
-        ""
-      ],
-      "Transfer creation gave response error": [
-        ""
-      ],
-      "Wire transfer created!": [
-        ""
-      ],
-      "Amount to withdraw:": [
-        ""
-      ],
-      "Withdraw": [
-        ""
-      ],
-      "No credentials given.": [
-        ""
-      ],
-      "Could not create withdrawal operation": [
-        ""
-      ],
-      "Withdrawal creation gave response error": [
-        ""
-      ],
-      "Obtain digital cash": [
-        ""
-      ],
-      "Transfer to bank account": [
-        ""
-      ],
-      "Date": [
-        ""
-      ],
-      "Amount": [
-        ""
-      ],
-      "Counterpart": [
-        ""
-      ],
-      "Subject": [
-        ""
-      ],
-      "Transfer to Taler Wallet": [
-        ""
-      ],
-      "Use this QR code to withdraw to your mobile wallet:": [
-        ""
-      ],
-      "Click %1$s to open your Taler wallet!": [
-        ""
-      ],
-      "Confirm Withdrawal": [
-        ""
-      ],
-      "Authorize withdrawal by solving challenge": [
-        ""
-      ],
-      "What is": [
-        ""
-      ],
-      "Answer is wrong.": [
-        ""
-      ],
-      "Confirm": [
-        ""
-      ],
-      "Cancel": [
-        ""
-      ],
-      "A this point, a %1$s bank would ask for an additional authentication 
proof (PIN/TAN, one time password, ..), instead of a simple calculation.": [
-        ""
-      ],
-      "No withdrawal ID found.": [
-        ""
-      ],
-      "Could not confirm the withdrawal": [
-        ""
-      ],
-      "Withdrawal confirmation gave response error": [
-        ""
-      ],
-      "Withdrawal confirmed!": [
-        ""
-      ],
-      "Could not abort the withdrawal.": [
-        ""
-      ],
-      "Withdrawal abortion failed.": [
-        ""
-      ],
-      "Withdrawal aborted!": [
-        ""
-      ],
-      "Abort": [
-        ""
-      ],
-      "withdrawal (%1$s) was never (correctly) created at the bank...": [
-        ""
-      ],
-      "Waiting the bank to create the operation...": [
-        ""
-      ],
-      "This withdrawal was aborted!": [
-        ""
-      ],
-      "Welcome to %1$s!": [
-        ""
-      ],
-      "Username or account label '%1$s' not found.  Won't login.": [
-        ""
-      ],
-      "Wrong credentials given.": [
-        ""
-      ],
-      "Account information could not be retrieved.": [
-        ""
-      ],
-      "Welcome, %1$s !": [
-        ""
-      ],
-      "Bank account balance": [
-        ""
-      ],
-      "Payments": [
-        ""
-      ],
-      "Latest transactions:": [
-        ""
-      ],
-      "List of public accounts was not found.": [
-        ""
-      ],
-      "List of public accounts could not be retrieved.": [
-        ""
-      ],
-      "History of public accounts": [
-        ""
-      ],
-      "Currently, the bank is not accepting new registrations!": [
-        ""
-      ],
-      "Use only letter and numbers starting with a lower case letter": [
-        ""
-      ],
-      "Password don't match": [
-        ""
-      ],
-      "Please register!": [
-        ""
-      ],
-      "Repeat Password:": [
-        ""
-      ],
-      "Registration failed, please report": [
-        ""
-      ],
-      "That username is already taken": [
-        ""
-      ],
-      "New registration gave response error": [
-        ""
-      ],
-      "Bank menu": [
-        ""
-      ],
-      "Select option1": [
-        ""
-      ],
-      "Select option2": [
-        ""
-      ],
-      "days": [
-        ""
-      ],
-      "hours": [
-        ""
-      ],
-      "minutes": [
-        ""
-      ],
-      "seconds": [
-        ""
-      ]
-    }
-  }
+      Logout: [""],
+      "Skip to main content": [""],
+      "This part of the demo shows how a bank that supports Taler directly 
would work. In addition to using your own bank account, you can also see the 
transaction history of some %1$s.":
+        [""],
+      "Taler logo": [""],
+      "Missing username": [""],
+      "Missing password": [""],
+      "Please login!": [""],
+      "Username:": [""],
+      "Password:": [""],
+      Login: [""],
+      Register: [""],
+      "Missing IBAN": [""],
+      "IBAN should have just uppercased letters and numbers": [""],
+      "Missing subject": [""],
+      "Missing amount": [""],
+      "Amount is not valid": [""],
+      "Should be greater than 0": [""],
+      "Receiver IBAN:": [""],
+      "Transfer subject:": [""],
+      "Amount:": [""],
+      "Field(s) missing.": [""],
+      "Want to try the raw payto://-format?": [""],
+      "Missing payto address": [""],
+      "Payto does not follow the pattern": [""],
+      "Transfer money to account identified by payto:// URI:": [""],
+      "payto URI:": [""],
+      "payto address": [""],
+      Send: [""],
+      "Use wire-transfer form?": [""],
+      "No credentials found.": [""],
+      "Could not create the wire transfer": [""],
+      "Transfer creation gave response error": [""],
+      "Wire transfer created!": [""],
+      "Amount to withdraw:": [""],
+      Withdraw: [""],
+      "No credentials given.": [""],
+      "Could not create withdrawal operation": [""],
+      "Withdrawal creation gave response error": [""],
+      "Obtain digital cash": [""],
+      "Transfer to bank account": [""],
+      Date: [""],
+      Amount: [""],
+      Counterpart: [""],
+      Subject: [""],
+      "Transfer to Taler Wallet": [""],
+      "Use this QR code to withdraw to your mobile wallet:": [""],
+      "Click %1$s to open your Taler wallet!": [""],
+      "Confirm Withdrawal": [""],
+      "Authorize withdrawal by solving challenge": [""],
+      "What is": [""],
+      "Answer is wrong.": [""],
+      Confirm: [""],
+      Cancel: [""],
+      "A this point, a %1$s bank would ask for an additional authentication 
proof (PIN/TAN, one time password, ..), instead of a simple calculation.":
+        [""],
+      "No withdrawal ID found.": [""],
+      "Could not confirm the withdrawal": [""],
+      "Withdrawal confirmation gave response error": [""],
+      "Withdrawal confirmed!": [""],
+      "Could not abort the withdrawal.": [""],
+      "Withdrawal abortion failed.": [""],
+      "Withdrawal aborted!": [""],
+      Abort: [""],
+      "withdrawal (%1$s) was never (correctly) created at the bank...": [""],
+      "Waiting the bank to create the operation...": [""],
+      "This withdrawal was aborted!": [""],
+      "Welcome to %1$s!": [""],
+      "Username or account label '%1$s' not found.  Won't login.": [""],
+      "Wrong credentials given.": [""],
+      "Account information could not be retrieved.": [""],
+      "Welcome, %1$s !": [""],
+      "Bank account balance": [""],
+      Payments: [""],
+      "Latest transactions:": [""],
+      "List of public accounts was not found.": [""],
+      "List of public accounts could not be retrieved.": [""],
+      "History of public accounts": [""],
+      "Currently, the bank is not accepting new registrations!": [""],
+      "Use only letter and numbers starting with a lower case letter": [""],
+      "Password don't match": [""],
+      "Please register!": [""],
+      "Repeat Password:": [""],
+      "Registration failed, please report": [""],
+      "That username is already taken": [""],
+      "New registration gave response error": [""],
+      "Bank menu": [""],
+      "Select option1": [""],
+      "Select option2": [""],
+      days: [""],
+      hours: [""],
+      minutes: [""],
+      seconds: [""],
+    },
+  },
 };
 
-strings['en'] = {
-  "domain": "messages",
-  "locale_data": {
-    "messages": {
+strings["en"] = {
+  domain: "messages",
+  locale_data: {
+    messages: {
       "": {
-        "domain": "messages",
-        "plural_forms": "nplurals=2; plural=(n != 1);",
-        "lang": "en"
+        domain: "messages",
+        plural_forms: "nplurals=2; plural=(n != 1);",
+        lang: "en",
       },
-      "Logout": [
-        ""
-      ],
-      "Skip to main content": [
-        ""
-      ],
-      "This part of the demo shows how a bank that supports Taler directly 
would work. In addition to using your own bank account, you can also see the 
transaction history of some %1$s.": [
-        ""
-      ],
-      "Taler logo": [
-        ""
-      ],
-      "Missing username": [
-        ""
-      ],
-      "Missing password": [
-        ""
-      ],
-      "Please login!": [
-        ""
-      ],
-      "Username:": [
-        ""
-      ],
-      "Password:": [
-        ""
-      ],
-      "Login": [
-        ""
-      ],
-      "Register": [
-        ""
-      ],
-      "Missing IBAN": [
-        ""
-      ],
-      "IBAN should have just uppercased letters and numbers": [
-        ""
-      ],
-      "Missing subject": [
-        ""
-      ],
-      "Missing amount": [
-        ""
-      ],
-      "Amount is not valid": [
-        ""
-      ],
-      "Should be greater than 0": [
-        ""
-      ],
-      "Receiver IBAN:": [
-        ""
-      ],
-      "Transfer subject:": [
-        ""
-      ],
-      "Amount:": [
-        ""
-      ],
-      "Field(s) missing.": [
-        ""
-      ],
-      "Want to try the raw payto://-format?": [
-        ""
-      ],
-      "Missing payto address": [
-        ""
-      ],
-      "Payto does not follow the pattern": [
-        ""
-      ],
-      "Transfer money to account identified by payto:// URI:": [
-        ""
-      ],
-      "payto URI:": [
-        ""
-      ],
-      "payto address": [
-        ""
-      ],
-      "Send": [
-        ""
-      ],
-      "Use wire-transfer form?": [
-        ""
-      ],
-      "No credentials found.": [
-        ""
-      ],
-      "Could not create the wire transfer": [
-        ""
-      ],
-      "Transfer creation gave response error": [
-        ""
-      ],
-      "Wire transfer created!": [
-        ""
-      ],
-      "Amount to withdraw:": [
-        "Amount to withdraw"
-      ],
-      "Withdraw": [
-        "Confirm withdrawal"
-      ],
-      "No credentials given.": [
-        ""
-      ],
-      "Could not create withdrawal operation": [
-        ""
-      ],
-      "Withdrawal creation gave response error": [
-        ""
-      ],
-      "Obtain digital cash": [
-        ""
-      ],
-      "Transfer to bank account": [
-        ""
-      ],
-      "Date": [
-        ""
-      ],
-      "Amount": [
-        ""
-      ],
-      "Counterpart": [
-        ""
-      ],
-      "Subject": [
-        ""
-      ],
-      "Transfer to Taler Wallet": [
-        "Charge Taler wallet"
-      ],
-      "Use this QR code to withdraw to your mobile wallet:": [
-        ""
-      ],
-      "Click %1$s to open your Taler wallet!": [
-        ""
-      ],
-      "Confirm Withdrawal": [
-        "Confirm withdrawal"
-      ],
-      "Authorize withdrawal by solving challenge": [
-        ""
-      ],
-      "What is": [
-        ""
-      ],
-      "Answer is wrong.": [
-        ""
-      ],
-      "Confirm": [
-        ""
-      ],
-      "Cancel": [
-        ""
-      ],
-      "A this point, a %1$s bank would ask for an additional authentication 
proof (PIN/TAN, one time password, ..), instead of a simple calculation.": [
-        ""
-      ],
-      "No withdrawal ID found.": [
-        ""
-      ],
-      "Could not confirm the withdrawal": [
-        "Confirm withdrawal"
-      ],
-      "Withdrawal confirmation gave response error": [
-        ""
-      ],
-      "Withdrawal confirmed!": [
-        ""
-      ],
-      "Could not abort the withdrawal.": [
-        "Close Taler withdrawal"
-      ],
-      "Withdrawal abortion failed.": [
-        ""
-      ],
-      "Withdrawal aborted!": [
-        ""
-      ],
-      "Abort": [
-        ""
-      ],
-      "withdrawal (%1$s) was never (correctly) created at the bank...": [
-        ""
-      ],
-      "Waiting the bank to create the operation...": [
-        ""
-      ],
-      "This withdrawal was aborted!": [
-        ""
-      ],
-      "Welcome to %1$s!": [
-        ""
-      ],
-      "Username or account label '%1$s' not found.  Won't login.": [
-        ""
-      ],
-      "Wrong credentials given.": [
-        ""
-      ],
-      "Account information could not be retrieved.": [
-        ""
-      ],
-      "Welcome, %1$s !": [
-        ""
-      ],
-      "Bank account balance": [
-        ""
-      ],
-      "Payments": [
-        ""
-      ],
-      "Latest transactions:": [
-        ""
-      ],
-      "List of public accounts was not found.": [
-        ""
-      ],
-      "List of public accounts could not be retrieved.": [
-        ""
-      ],
-      "History of public accounts": [
-        ""
-      ],
-      "Currently, the bank is not accepting new registrations!": [
-        ""
-      ],
-      "Use only letter and numbers starting with a lower case letter": [
-        ""
-      ],
-      "Password don't match": [
-        ""
-      ],
-      "Please register!": [
-        ""
-      ],
-      "Repeat Password:": [
-        ""
-      ],
-      "Registration failed, please report": [
-        ""
-      ],
-      "That username is already taken": [
-        ""
-      ],
-      "New registration gave response error": [
-        ""
-      ],
-      "Bank menu": [
-        ""
-      ],
-      "Select option1": [
-        ""
-      ],
-      "Select option2": [
-        ""
-      ],
-      "days": [
-        "days"
-      ],
-      "hours": [
-        "hours"
-      ],
-      "minutes": [
-        "minutes"
-      ],
-      "seconds": [
-        "seconds"
-      ]
-    }
-  }
+      Logout: [""],
+      "Skip to main content": [""],
+      "This part of the demo shows how a bank that supports Taler directly 
would work. In addition to using your own bank account, you can also see the 
transaction history of some %1$s.":
+        [""],
+      "Taler logo": [""],
+      "Missing username": [""],
+      "Missing password": [""],
+      "Please login!": [""],
+      "Username:": [""],
+      "Password:": [""],
+      Login: [""],
+      Register: [""],
+      "Missing IBAN": [""],
+      "IBAN should have just uppercased letters and numbers": [""],
+      "Missing subject": [""],
+      "Missing amount": [""],
+      "Amount is not valid": [""],
+      "Should be greater than 0": [""],
+      "Receiver IBAN:": [""],
+      "Transfer subject:": [""],
+      "Amount:": [""],
+      "Field(s) missing.": [""],
+      "Want to try the raw payto://-format?": [""],
+      "Missing payto address": [""],
+      "Payto does not follow the pattern": [""],
+      "Transfer money to account identified by payto:// URI:": [""],
+      "payto URI:": [""],
+      "payto address": [""],
+      Send: [""],
+      "Use wire-transfer form?": [""],
+      "No credentials found.": [""],
+      "Could not create the wire transfer": [""],
+      "Transfer creation gave response error": [""],
+      "Wire transfer created!": [""],
+      "Amount to withdraw:": ["Amount to withdraw"],
+      Withdraw: ["Confirm withdrawal"],
+      "No credentials given.": [""],
+      "Could not create withdrawal operation": [""],
+      "Withdrawal creation gave response error": [""],
+      "Obtain digital cash": [""],
+      "Transfer to bank account": [""],
+      Date: [""],
+      Amount: [""],
+      Counterpart: [""],
+      Subject: [""],
+      "Transfer to Taler Wallet": ["Charge Taler wallet"],
+      "Use this QR code to withdraw to your mobile wallet:": [""],
+      "Click %1$s to open your Taler wallet!": [""],
+      "Confirm Withdrawal": ["Confirm withdrawal"],
+      "Authorize withdrawal by solving challenge": [""],
+      "What is": [""],
+      "Answer is wrong.": [""],
+      Confirm: [""],
+      Cancel: [""],
+      "A this point, a %1$s bank would ask for an additional authentication 
proof (PIN/TAN, one time password, ..), instead of a simple calculation.":
+        [""],
+      "No withdrawal ID found.": [""],
+      "Could not confirm the withdrawal": ["Confirm withdrawal"],
+      "Withdrawal confirmation gave response error": [""],
+      "Withdrawal confirmed!": [""],
+      "Could not abort the withdrawal.": ["Close Taler withdrawal"],
+      "Withdrawal abortion failed.": [""],
+      "Withdrawal aborted!": [""],
+      Abort: [""],
+      "withdrawal (%1$s) was never (correctly) created at the bank...": [""],
+      "Waiting the bank to create the operation...": [""],
+      "This withdrawal was aborted!": [""],
+      "Welcome to %1$s!": [""],
+      "Username or account label '%1$s' not found.  Won't login.": [""],
+      "Wrong credentials given.": [""],
+      "Account information could not be retrieved.": [""],
+      "Welcome, %1$s !": [""],
+      "Bank account balance": [""],
+      Payments: [""],
+      "Latest transactions:": [""],
+      "List of public accounts was not found.": [""],
+      "List of public accounts could not be retrieved.": [""],
+      "History of public accounts": [""],
+      "Currently, the bank is not accepting new registrations!": [""],
+      "Use only letter and numbers starting with a lower case letter": [""],
+      "Password don't match": [""],
+      "Please register!": [""],
+      "Repeat Password:": [""],
+      "Registration failed, please report": [""],
+      "That username is already taken": [""],
+      "New registration gave response error": [""],
+      "Bank menu": [""],
+      "Select option1": [""],
+      "Select option2": [""],
+      days: ["days"],
+      hours: ["hours"],
+      minutes: ["minutes"],
+      seconds: ["seconds"],
+    },
+  },
 };
 
-strings['es'] = {
-  "domain": "messages",
-  "locale_data": {
-    "messages": {
+strings["es"] = {
+  domain: "messages",
+  locale_data: {
+    messages: {
       "": {
-        "domain": "messages",
-        "plural_forms": "nplurals=2; plural=n != 1;",
-        "lang": "es"
+        domain: "messages",
+        plural_forms: "nplurals=2; plural=n != 1;",
+        lang: "es",
       },
-      "Logout": [
-        "Cierre de sesión"
-      ],
-      "Skip to main content": [
-        "Saltar el menú de navegación"
-      ],
-      "This part of the demo shows how a bank that supports Taler directly 
would work. In addition to using your own bank account, you can also see the 
transaction history of some %1$s.": [
-        "Esta parte de la demostración muestra cómo funciona un banco que 
soporta Taler directamente. Además de usar tu propia cuenta de banco, también 
podrás ver el historial de transacciones de algunas %1$s."
-      ],
-      "Taler logo": [
-        "Logo Taler"
-      ],
-      "Missing username": [
-        "Falta nombre de usuario"
-      ],
-      "Missing password": [
-        "Falta contraseña"
-      ],
-      "Please login!": [
-        "Por favor inicia sesión!"
-      ],
-      "Username:": [
-        "Nombre de usuario:"
-      ],
-      "Password:": [
-        "Password:"
-      ],
-      "Login": [
-        "Iniciar sesión"
-      ],
-      "Register": [
-        "Registrarse"
-      ],
-      "Missing IBAN": [
-        "Falta IBAN"
-      ],
+      Logout: ["Cierre de sesión"],
+      "Skip to main content": ["Saltar el menú de navegación"],
+      "This part of the demo shows how a bank that supports Taler directly 
would work. In addition to using your own bank account, you can also see the 
transaction history of some %1$s.":
+        [
+          "Esta parte de la demostración muestra cómo funciona un banco que 
soporta Taler directamente. Además de usar tu propia cuenta de banco, también 
podrás ver el historial de transacciones de algunas %1$s.",
+        ],
+      "Taler logo": ["Logo Taler"],
+      "Missing username": ["Falta nombre de usuario"],
+      "Missing password": ["Falta contraseña"],
+      "Please login!": ["Por favor inicia sesión!"],
+      "Username:": ["Nombre de usuario:"],
+      "Password:": ["Password:"],
+      Login: ["Iniciar sesión"],
+      Register: ["Registrarse"],
+      "Missing IBAN": ["Falta IBAN"],
       "IBAN should have just uppercased letters and numbers": [
-        "IBAN debería tener letras mayúsculas y números"
-      ],
-      "Missing subject": [
-        "Falta asunto"
-      ],
-      "Missing amount": [
-        "Falta monto"
-      ],
-      "Amount is not valid": [
-        "Monto no válido"
-      ],
-      "Should be greater than 0": [
-        "Debería ser mas grande que 0"
-      ],
-      "Receiver IBAN:": [
-        "IBAN receptor:"
-      ],
-      "Transfer subject:": [
-        "Asunto de transferencia:"
-      ],
-      "Amount:": [
-        "Monto:"
-      ],
-      "Field(s) missing.": [
-        "Faltan campo(s)."
-      ],
+        "IBAN debería tener letras mayúsculas y números",
+      ],
+      "Missing subject": ["Falta asunto"],
+      "Missing amount": ["Falta monto"],
+      "Amount is not valid": ["Monto no válido"],
+      "Should be greater than 0": ["Debería ser mas grande que 0"],
+      "Receiver IBAN:": ["IBAN receptor:"],
+      "Transfer subject:": ["Asunto de transferencia:"],
+      "Amount:": ["Monto:"],
+      "Field(s) missing.": ["Faltan campo(s)."],
       "Want to try the raw payto://-format?": [
-        "Quieres probar el formato payto:// ?"
-      ],
-      "Missing payto address": [
-        "Falta direccion payto"
-      ],
-      "Payto does not follow the pattern": [
-        "Payto no sigue el patrón"
+        "Quieres probar el formato payto:// ?",
       ],
+      "Missing payto address": ["Falta direccion payto"],
+      "Payto does not follow the pattern": ["Payto no sigue el patrón"],
       "Transfer money to account identified by payto:// URI:": [
-        "Transferir dinero a la cuenta identificada por la URI payto://:"
-      ],
-      "payto URI:": [
-        "payto URI:"
-      ],
-      "payto address": [
-        "direccion payto"
-      ],
-      "Send": [
-        "Envíar"
+        "Transferir dinero a la cuenta identificada por la URI payto://:",
       ],
+      "payto URI:": ["payto URI:"],
+      "payto address": ["direccion payto"],
+      Send: ["Envíar"],
       "Use wire-transfer form?": [
-        "Usar el formulario de transferencia bancaria?"
-      ],
-      "No credentials found.": [
-        "Se dieron las credenciales incorrectas."
+        "Usar el formulario de transferencia bancaria?",
       ],
+      "No credentials found.": ["Se dieron las credenciales incorrectas."],
       "Could not create the wire transfer": [
-        "No se pudo create la transferencia bancaria"
+        "No se pudo create la transferencia bancaria",
       ],
       "Transfer creation gave response error": [
-        "La creación de la transferencia dió una respuesta erronea"
-      ],
-      "Wire transfer created!": [
-        "Transferencia bancaria creada!"
-      ],
-      "Amount to withdraw:": [
-        "Monto a retirar:"
-      ],
-      "Withdraw": [
-        "Retirar"
-      ],
-      "No credentials given.": [
-        "Se dieron las credenciales incorrectas."
+        "La creación de la transferencia dió una respuesta erronea",
       ],
+      "Wire transfer created!": ["Transferencia bancaria creada!"],
+      "Amount to withdraw:": ["Monto a retirar:"],
+      Withdraw: ["Retirar"],
+      "No credentials given.": ["Se dieron las credenciales incorrectas."],
       "Could not create withdrawal operation": [
-        "No se pude create la operación de retiro"
+        "No se pude create la operación de retiro",
       ],
       "Withdrawal creation gave response error": [
-        "La creación de retiro dió una respuesta errónea"
-      ],
-      "Obtain digital cash": [
-        "Obtener dinero digital"
-      ],
-      "Transfer to bank account": [
-        "Transferir a una cuenta bancaria"
-      ],
-      "Date": [
-        "Fecha"
-      ],
-      "Amount": [
-        "Monto"
-      ],
-      "Counterpart": [
-        "Contraparte"
-      ],
-      "Subject": [
-        "Asunto"
-      ],
-      "Transfer to Taler Wallet": [
-        "Transferir a una cartera Taler"
-      ],
+        "La creación de retiro dió una respuesta errónea",
+      ],
+      "Obtain digital cash": ["Obtener dinero digital"],
+      "Transfer to bank account": ["Transferir a una cuenta bancaria"],
+      Date: ["Fecha"],
+      Amount: ["Monto"],
+      Counterpart: ["Contraparte"],
+      Subject: ["Asunto"],
+      "Transfer to Taler Wallet": ["Transferir a una cartera Taler"],
       "Use this QR code to withdraw to your mobile wallet:": [
-        "Usar el código QR para retirar a tu cartera móvil:"
+        "Usar el código QR para retirar a tu cartera móvil:",
       ],
       "Click %1$s to open your Taler wallet!": [
-        "Click %1$s para abrir una cartera Taler!"
-      ],
-      "Confirm Withdrawal": [
-        "Confirmar retirada"
+        "Click %1$s para abrir una cartera Taler!",
       ],
+      "Confirm Withdrawal": ["Confirmar retirada"],
       "Authorize withdrawal by solving challenge": [
-        "Autorizar retiro resolviendo una pregunta"
-      ],
-      "What is": [
-        "Cuanto es"
-      ],
-      "Answer is wrong.": [
-        "La respuesta es incorrecta."
-      ],
-      "Confirm": [
-        "Confirmar"
-      ],
-      "Cancel": [
-        "Cancelar"
-      ],
-      "A this point, a %1$s bank would ask for an additional authentication 
proof (PIN/TAN, one time password, ..), instead of a simple calculation.": [
-        "En este punto, un banco %1$s preguntaría por una prueba adicional de 
autenticación (PIN/TAN, password de un solo uso, ....), en vez de un simple 
cálculo."
-      ],
-      "No withdrawal ID found.": [
-        "No ID de retiro encontrado."
-      ],
-      "Could not confirm the withdrawal": [
-        "No se pudo confirmar la retirada"
-      ],
+        "Autorizar retiro resolviendo una pregunta",
+      ],
+      "What is": ["Cuanto es"],
+      "Answer is wrong.": ["La respuesta es incorrecta."],
+      Confirm: ["Confirmar"],
+      Cancel: ["Cancelar"],
+      "A this point, a %1$s bank would ask for an additional authentication 
proof (PIN/TAN, one time password, ..), instead of a simple calculation.":
+        [
+          "En este punto, un banco %1$s preguntaría por una prueba adicional 
de autenticación (PIN/TAN, password de un solo uso, ....), en vez de un simple 
cálculo.",
+        ],
+      "No withdrawal ID found.": ["No ID de retiro encontrado."],
+      "Could not confirm the withdrawal": ["No se pudo confirmar la retirada"],
       "Withdrawal confirmation gave response error": [
-        "La confirmación de retiro dió una respuesta errónea"
-      ],
-      "Withdrawal confirmed!": [
-        "El retiro fue confirmado!"
-      ],
-      "Could not abort the withdrawal.": [
-        "No se pudo cancelar el retiro."
-      ],
-      "Withdrawal abortion failed.": [
-        "La cancelación del retiro falló."
-      ],
-      "Withdrawal aborted!": [
-        "Este retiro fue cancelado!"
-      ],
-      "Abort": [
-        "Cancelar"
+        "La confirmación de retiro dió una respuesta errónea",
       ],
+      "Withdrawal confirmed!": ["El retiro fue confirmado!"],
+      "Could not abort the withdrawal.": ["No se pudo cancelar el retiro."],
+      "Withdrawal abortion failed.": ["La cancelación del retiro falló."],
+      "Withdrawal aborted!": ["Este retiro fue cancelado!"],
+      Abort: ["Cancelar"],
       "withdrawal (%1$s) was never (correctly) created at the bank...": [
-        "retiro (%1$s) nunca fue (correctamente) generado en el banco..."
+        "retiro (%1$s) nunca fue (correctamente) generado en el banco...",
       ],
       "Waiting the bank to create the operation...": [
-        "Esperando que el banco genere la operación...."
-      ],
-      "This withdrawal was aborted!": [
-        "Este retiro fue cancelado!"
-      ],
-      "Welcome to %1$s!": [
-        "Bienvenido a %1$s!"
+        "Esperando que el banco genere la operación....",
       ],
+      "This withdrawal was aborted!": ["Este retiro fue cancelado!"],
+      "Welcome to %1$s!": ["Bienvenido a %1$s!"],
       "Username or account label '%1$s' not found.  Won't login.": [
-        "Nombre de usuario o etiqueta de cuenta '%1$s' no encontrada. No se 
iniciará sesión."
-      ],
-      "Wrong credentials given.": [
-        "Se dieron las credenciales incorrectas."
+        "Nombre de usuario o etiqueta de cuenta '%1$s' no encontrada. No se 
iniciará sesión.",
       ],
+      "Wrong credentials given.": ["Se dieron las credenciales incorrectas."],
       "Account information could not be retrieved.": [
-        "La información de la cuenta no pudo ser accedida."
-      ],
-      "Welcome, %1$s !": [
-        "Bienvenido/a, %1$s!"
-      ],
-      "Bank account balance": [
-        "Balance de cuenta bancaria"
-      ],
-      "Payments": [
-        "Pagos"
-      ],
-      "Latest transactions:": [
-        "Últimas transacciones:"
+        "La información de la cuenta no pudo ser accedida.",
       ],
+      "Welcome, %1$s !": ["Bienvenido/a, %1$s!"],
+      "Bank account balance": ["Balance de cuenta bancaria"],
+      Payments: ["Pagos"],
+      "Latest transactions:": ["Últimas transacciones:"],
       "List of public accounts was not found.": [
-        "La lista de cuentas públicas no fue encontrada."
+        "La lista de cuentas públicas no fue encontrada.",
       ],
       "List of public accounts could not be retrieved.": [
-        "La lista de cuentas públicas no pudo ser accedida."
-      ],
-      "History of public accounts": [
-        "Historial de cuentas públicas"
+        "La lista de cuentas públicas no pudo ser accedida.",
       ],
+      "History of public accounts": ["Historial de cuentas públicas"],
       "Currently, the bank is not accepting new registrations!": [
-        "Actualmente, el banco no está aceptado nuevos registros!"
+        "Actualmente, el banco no está aceptado nuevos registros!",
       ],
       "Use only letter and numbers starting with a lower case letter": [
-        "Solo use letras y números comenzando con una letra minúscula"
-      ],
-      "Password don't match": [
-        "La contraseña no coincide"
-      ],
-      "Please register!": [
-        "Por favor, registrese!"
-      ],
-      "Repeat Password:": [
-        "Repita la contraseña:"
+        "Solo use letras y números comenzando con una letra minúscula",
       ],
+      "Password don't match": ["La contraseña no coincide"],
+      "Please register!": ["Por favor, registrese!"],
+      "Repeat Password:": ["Repita la contraseña:"],
       "Registration failed, please report": [
-        "El registro falló, por favor reportelo"
+        "El registro falló, por favor reportelo",
       ],
       "That username is already taken": [
-        "El nombre del usuario ya está tomado"
+        "El nombre del usuario ya está tomado",
       ],
       "New registration gave response error": [
-        "Nuevo registro dió una respuesta errónea"
-      ],
-      "Bank menu": [
-        "Menu del banco"
-      ],
-      "Select option1": [
-        "Seleccione opción 1"
-      ],
-      "Select option2": [
-        "Seleccione opción 2"
-      ],
-      "days": [
-        "días"
-      ],
-      "hours": [
-        "horas"
-      ],
-      "minutes": [
-        "minutos"
-      ],
-      "seconds": [
-        "segundos"
-      ]
-    }
-  }
+        "Nuevo registro dió una respuesta errónea",
+      ],
+      "Bank menu": ["Menu del banco"],
+      "Select option1": ["Seleccione opción 1"],
+      "Select option2": ["Seleccione opción 2"],
+      days: ["días"],
+      hours: ["horas"],
+      minutes: ["minutos"],
+      seconds: ["segundos"],
+    },
+  },
 };
 
-strings['it'] = {
-  "domain": "messages",
-  "locale_data": {
-    "messages": {
+strings["it"] = {
+  domain: "messages",
+  locale_data: {
+    messages: {
       "": {
-        "domain": "messages",
-        "plural_forms": "nplurals=2; plural=(n != 1);",
-        "lang": "it"
+        domain: "messages",
+        plural_forms: "nplurals=2; plural=(n != 1);",
+        lang: "it",
       },
-      "Logout": [
-        ""
-      ],
-      "Skip to main content": [
-        ""
-      ],
-      "This part of the demo shows how a bank that supports Taler directly 
would work. In addition to using your own bank account, you can also see the 
transaction history of some %1$s.": [
-        ""
-      ],
-      "Taler logo": [
-        ""
-      ],
-      "Missing username": [
-        ""
-      ],
-      "Missing password": [
-        ""
-      ],
-      "Please login!": [
-        "Accedi!"
-      ],
-      "Username:": [
-        ""
-      ],
-      "Password:": [
-        ""
-      ],
-      "Login": [
-        "Accedi"
-      ],
-      "Register": [
-        "Registrati"
-      ],
-      "Missing IBAN": [
-        ""
-      ],
-      "IBAN should have just uppercased letters and numbers": [
-        ""
-      ],
-      "Missing subject": [
-        ""
-      ],
-      "Missing amount": [
-        ""
-      ],
-      "Amount is not valid": [
-        ""
-      ],
-      "Should be greater than 0": [
-        ""
-      ],
-      "Receiver IBAN:": [
-        ""
-      ],
-      "Transfer subject:": [
-        ""
-      ],
-      "Amount:": [
-        "Somma"
-      ],
-      "Field(s) missing.": [
-        ""
-      ],
+      Logout: [""],
+      "Skip to main content": [""],
+      "This part of the demo shows how a bank that supports Taler directly 
would work. In addition to using your own bank account, you can also see the 
transaction history of some %1$s.":
+        [""],
+      "Taler logo": [""],
+      "Missing username": [""],
+      "Missing password": [""],
+      "Please login!": ["Accedi!"],
+      "Username:": [""],
+      "Password:": [""],
+      Login: ["Accedi"],
+      Register: ["Registrati"],
+      "Missing IBAN": [""],
+      "IBAN should have just uppercased letters and numbers": [""],
+      "Missing subject": [""],
+      "Missing amount": [""],
+      "Amount is not valid": [""],
+      "Should be greater than 0": [""],
+      "Receiver IBAN:": [""],
+      "Transfer subject:": [""],
+      "Amount:": ["Somma"],
+      "Field(s) missing.": [""],
       "Want to try the raw payto://-format?": [
-        "Prova il trasferimento tramite il formato Payto!"
-      ],
-      "Missing payto address": [
-        "indirizzo Payto"
-      ],
-      "Payto does not follow the pattern": [
-        ""
+        "Prova il trasferimento tramite il formato Payto!",
       ],
+      "Missing payto address": ["indirizzo Payto"],
+      "Payto does not follow the pattern": [""],
       "Transfer money to account identified by payto:// URI:": [
-        "Trasferisci fondi a un altro conto di questa banca:"
-      ],
-      "payto URI:": [
-        ""
-      ],
-      "payto address": [
-        "indirizzo Payto"
-      ],
-      "Send": [
-        ""
-      ],
-      "Use wire-transfer form?": [
-        "Chiudi il bonifico"
-      ],
-      "No credentials found.": [
-        "Credenziali invalide."
-      ],
-      "Could not create the wire transfer": [
-        ""
-      ],
-      "Transfer creation gave response error": [
-        ""
-      ],
-      "Wire transfer created!": [
-        "Bonifico"
-      ],
-      "Amount to withdraw:": [
-        "Somma da ritirare"
-      ],
-      "Withdraw": [
-        "Conferma il ritiro"
-      ],
-      "No credentials given.": [
-        "Credenziali invalide."
-      ],
-      "Could not create withdrawal operation": [
-        ""
-      ],
-      "Withdrawal creation gave response error": [
-        ""
-      ],
-      "Obtain digital cash": [
-        ""
-      ],
+        "Trasferisci fondi a un altro conto di questa banca:",
+      ],
+      "payto URI:": [""],
+      "payto address": ["indirizzo Payto"],
+      Send: [""],
+      "Use wire-transfer form?": ["Chiudi il bonifico"],
+      "No credentials found.": ["Credenziali invalide."],
+      "Could not create the wire transfer": [""],
+      "Transfer creation gave response error": [""],
+      "Wire transfer created!": ["Bonifico"],
+      "Amount to withdraw:": ["Somma da ritirare"],
+      Withdraw: ["Conferma il ritiro"],
+      "No credentials given.": ["Credenziali invalide."],
+      "Could not create withdrawal operation": [""],
+      "Withdrawal creation gave response error": [""],
+      "Obtain digital cash": [""],
       "Transfer to bank account": [
-        "Trasferisci fondi a un altro conto di questa banca:"
-      ],
-      "Date": [
-        ""
-      ],
-      "Amount": [
-        "Somma"
-      ],
-      "Counterpart": [
-        "Controparte"
-      ],
-      "Subject": [
-        "Causale"
-      ],
-      "Transfer to Taler Wallet": [
-        "Ritira contante nel portafoglio Taler"
+        "Trasferisci fondi a un altro conto di questa banca:",
       ],
+      Date: [""],
+      Amount: ["Somma"],
+      Counterpart: ["Controparte"],
+      Subject: ["Causale"],
+      "Transfer to Taler Wallet": ["Ritira contante nel portafoglio Taler"],
       "Use this QR code to withdraw to your mobile wallet:": [
-        "Usa questo codice QR per ritirare contante nel tuo wallet:"
-      ],
-      "Click %1$s to open your Taler wallet!": [
-        ""
-      ],
-      "Confirm Withdrawal": [
-        "Conferma il ritiro"
-      ],
-      "Authorize withdrawal by solving challenge": [
-        ""
-      ],
-      "What is": [
-        ""
-      ],
-      "Answer is wrong.": [
-        ""
-      ],
-      "Confirm": [
-        "Conferma"
-      ],
-      "Cancel": [
-        ""
-      ],
-      "A this point, a %1$s bank would ask for an additional authentication 
proof (PIN/TAN, one time password, ..), instead of a simple calculation.": [
-        ""
-      ],
-      "No withdrawal ID found.": [
-        ""
-      ],
-      "Could not confirm the withdrawal": [
-        "Conferma il ritiro"
-      ],
-      "Withdrawal confirmation gave response error": [
-        ""
-      ],
-      "Withdrawal confirmed!": [
-        "Questo ritiro è stato annullato!"
-      ],
-      "Could not abort the withdrawal.": [
-        "Chiudi il ritiro Taler"
-      ],
-      "Withdrawal abortion failed.": [
-        "Questo ritiro è stato annullato!"
-      ],
-      "Withdrawal aborted!": [
-        "Questo ritiro è stato annullato!"
-      ],
-      "Abort": [
-        "Annulla"
-      ],
-      "withdrawal (%1$s) was never (correctly) created at the bank...": [
-        ""
-      ],
+        "Usa questo codice QR per ritirare contante nel tuo wallet:",
+      ],
+      "Click %1$s to open your Taler wallet!": [""],
+      "Confirm Withdrawal": ["Conferma il ritiro"],
+      "Authorize withdrawal by solving challenge": [""],
+      "What is": [""],
+      "Answer is wrong.": [""],
+      Confirm: ["Conferma"],
+      Cancel: [""],
+      "A this point, a %1$s bank would ask for an additional authentication 
proof (PIN/TAN, one time password, ..), instead of a simple calculation.":
+        [""],
+      "No withdrawal ID found.": [""],
+      "Could not confirm the withdrawal": ["Conferma il ritiro"],
+      "Withdrawal confirmation gave response error": [""],
+      "Withdrawal confirmed!": ["Questo ritiro è stato annullato!"],
+      "Could not abort the withdrawal.": ["Chiudi il ritiro Taler"],
+      "Withdrawal abortion failed.": ["Questo ritiro è stato annullato!"],
+      "Withdrawal aborted!": ["Questo ritiro è stato annullato!"],
+      Abort: ["Annulla"],
+      "withdrawal (%1$s) was never (correctly) created at the bank...": [""],
       "Waiting the bank to create the operation...": [
-        "La banca sta creando l'operazione..."
-      ],
-      "This withdrawal was aborted!": [
-        "Questo ritiro è stato annullato!"
-      ],
-      "Welcome to %1$s!": [
-        ""
+        "La banca sta creando l'operazione...",
       ],
+      "This withdrawal was aborted!": ["Questo ritiro è stato annullato!"],
+      "Welcome to %1$s!": [""],
       "Username or account label '%1$s' not found.  Won't login.": [
-        "L'utente '%1$s' non esiste.  Login impossibile"
-      ],
-      "Wrong credentials given.": [
-        "Credenziali invalide."
+        "L'utente '%1$s' non esiste.  Login impossibile",
       ],
+      "Wrong credentials given.": ["Credenziali invalide."],
       "Account information could not be retrieved.": [
-        "Impossibile ricevere le informazioni relative al conto."
-      ],
-      "Welcome, %1$s !": [
-        ""
-      ],
-      "Bank account balance": [
-        "Bilancio:"
-      ],
-      "Payments": [
-        ""
-      ],
-      "Latest transactions:": [
-        "Ultime transazioni:"
+        "Impossibile ricevere le informazioni relative al conto.",
       ],
+      "Welcome, %1$s !": [""],
+      "Bank account balance": ["Bilancio:"],
+      Payments: [""],
+      "Latest transactions:": ["Ultime transazioni:"],
       "List of public accounts was not found.": [
-        "Lista conti pubblici non trovata."
+        "Lista conti pubblici non trovata.",
       ],
       "List of public accounts could not be retrieved.": [
-        "Lista conti pubblici non pervenuta."
-      ],
-      "History of public accounts": [
-        "Storico dei conti pubblici"
-      ],
-      "Currently, the bank is not accepting new registrations!": [
-        ""
-      ],
-      "Use only letter and numbers starting with a lower case letter": [
-        ""
-      ],
-      "Password don't match": [
-        ""
-      ],
-      "Please register!": [
-        "Accedi!"
-      ],
-      "Repeat Password:": [
-        ""
-      ],
-      "Registration failed, please report": [
-        "Registrazione"
-      ],
-      "That username is already taken": [
-        ""
-      ],
-      "New registration gave response error": [
-        ""
-      ],
-      "Bank menu": [
-        ""
-      ],
-      "Select option1": [
-        ""
-      ],
-      "Select option2": [
-        ""
-      ],
-      "days": [
-        ""
-      ],
-      "hours": [
-        ""
-      ],
-      "minutes": [
-        ""
-      ],
-      "seconds": [
-        ""
-      ]
-    }
-  }
+        "Lista conti pubblici non pervenuta.",
+      ],
+      "History of public accounts": ["Storico dei conti pubblici"],
+      "Currently, the bank is not accepting new registrations!": [""],
+      "Use only letter and numbers starting with a lower case letter": [""],
+      "Password don't match": [""],
+      "Please register!": ["Accedi!"],
+      "Repeat Password:": [""],
+      "Registration failed, please report": ["Registrazione"],
+      "That username is already taken": [""],
+      "New registration gave response error": [""],
+      "Bank menu": [""],
+      "Select option1": [""],
+      "Select option2": [""],
+      days: [""],
+      hours: [""],
+      minutes: [""],
+      seconds: [""],
+    },
+  },
 };
-
diff --git a/packages/demobank-ui/src/pages/LoginForm.tsx 
b/packages/demobank-ui/src/pages/LoginForm.tsx
index 0acced4ab..dd0364d6e 100644
--- a/packages/demobank-ui/src/pages/LoginForm.tsx
+++ b/packages/demobank-ui/src/pages/LoginForm.tsx
@@ -44,7 +44,13 @@ export function LoginForm(): VNode {
 
   return (
     <div class="login-div">
-      <form action="javascript:void(0);" class="login-form" noValidate>
+      <form
+        class="login-form"
+        noValidate
+        onSubmit={(e) => {
+          e.preventDefault();
+        }}
+      >
         <div class="pure-form">
           <h2>{i18n.str`Please login!`}</h2>
           <p class="unameFieldLabel loginFieldLabel formFieldLabel">
@@ -87,10 +93,11 @@ export function LoginForm(): VNode {
           />
           <br />
           <button
-            type="button"
+            type="submit"
             class="pure-button pure-button-primary"
             disabled={!!errors}
-            onClick={() => {
+            onClick={(e) => {
+              e.preventDefault();
               if (!username || !password) return;
               loginCall({ username, password }, backend);
               setUsername(undefined);
@@ -103,7 +110,8 @@ export function LoginForm(): VNode {
           {bankUiSettings.allowRegistrations ? (
             <button
               class="pure-button pure-button-secondary btn-cancel"
-              onClick={() => {
+              onClick={(e) => {
+                e.preventDefault();
                 route("/register");
               }}
             >
diff --git a/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx 
b/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx
index 3f048c385..1922eeed3 100644
--- a/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx
+++ b/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx
@@ -74,7 +74,13 @@ export function PaytoWireTransferForm({
   if (!pageState.isRawPayto)
     return (
       <div>
-        <form class="pure-form" name="wire-transfer-form">
+        <form
+          class="pure-form"
+          name="wire-transfer-form"
+          onSubmit={(e) => {
+            e.preventDefault();
+          }}
+        >
           <p>
             <label for="iban">{i18n.str`Receiver IBAN:`}</label>&nbsp;
             <input
@@ -155,11 +161,12 @@ export function PaytoWireTransferForm({
 
           <p style={{ display: "flex", justifyContent: "space-between" }}>
             <input
-              type="button"
+              type="submit"
               class="pure-button pure-button-primary"
               disabled={!!errorsWire}
               value="Send"
-              onClick={async () => {
+              onClick={async (e) => {
+                e.preventDefault();
                 if (
                   typeof submitData === "undefined" ||
                   typeof submitData.iban === "undefined" ||
@@ -203,7 +210,8 @@ export function PaytoWireTransferForm({
               type="button"
               class="pure-button"
               value="Clear"
-              onClick={async () => {
+              onClick={async (e) => {
+                e.preventDefault();
                 submitDataSetter((p) => ({
                   amount: undefined,
                   iban: undefined,
diff --git a/packages/demobank-ui/src/pages/QrCodeSection.tsx 
b/packages/demobank-ui/src/pages/QrCodeSection.tsx
index 59a8ccd61..e02c6efb1 100644
--- a/packages/demobank-ui/src/pages/QrCodeSection.tsx
+++ b/packages/demobank-ui/src/pages/QrCodeSection.tsx
@@ -46,8 +46,19 @@ export function QrCodeSection({
           <p>
             <i18n.Translate>
               Click{" "}
-              <a id="linkqr" href={talerWithdrawUri}>{i18n.str`this 
link`}</a>{" "}
-              to open your Taler wallet!
+              <a
+                id="linkqr"
+                href={talerWithdrawUri}
+              >{i18n.str`this taler:// link`}</a>{" "}
+              to open your Taler wallet
+            </i18n.Translate>{" "}
+            <i18n.Translate>
+              or try{" "}
+              <a
+                id="linkqr"
+                href={"ext+" + talerWithdrawUri}
+              >{i18n.str`this ext+taler:// link`}</a>{" "}
+              if your browser does not support <b>taler://</b> scheme.
             </i18n.Translate>
           </p>
           <br />
diff --git a/packages/demobank-ui/src/pages/RegistrationPage.tsx 
b/packages/demobank-ui/src/pages/RegistrationPage.tsx
index 9d84cdf44..183fa993e 100644
--- a/packages/demobank-ui/src/pages/RegistrationPage.tsx
+++ b/packages/demobank-ui/src/pages/RegistrationPage.tsx
@@ -84,7 +84,13 @@ function RegistrationForm(): VNode {
       <h1 class="nav">{i18n.str`Welcome to ${bankUiSettings.bankName}!`}</h1>
       <article>
         <div class="register-div">
-          <form class="register-form" noValidate>
+          <form
+            class="register-form"
+            noValidate
+            onSubmit={(e) => {
+              e.preventDefault();
+            }}
+          >
             <div class="pure-form">
               <h2>{i18n.str`Please register!`}</h2>
               <p class="unameFieldLabel registerFieldLabel formFieldLabel">
@@ -144,8 +150,10 @@ function RegistrationForm(): VNode {
               <br />
               <button
                 class="pure-button pure-button-primary btn-register"
+                type="submit"
                 disabled={!!errors}
-                onClick={() => {
+                onClick={(e) => {
+                  e.preventDefault();
                   if (!username || !password) return;
                   registrationCall(
                     { username, password },
@@ -164,7 +172,8 @@ function RegistrationForm(): VNode {
               {/* FIXME: should use a different color */}
               <button
                 class="pure-button pure-button-secondary btn-cancel"
-                onClick={() => {
+                onClick={(e) => {
+                  e.preventDefault();
                   setUsername(undefined);
                   setPassword(undefined);
                   setRepeatPassword(undefined);
diff --git a/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx 
b/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx
index 1df86717b..17fb85592 100644
--- a/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx
+++ b/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx
@@ -45,7 +45,14 @@ export function WalletWithdrawForm({
     if (focus) ref.current?.focus();
   }, [focus]);
   return (
-    <form id="reserve-form" class="pure-form" name="tform">
+    <form
+      id="reserve-form"
+      class="pure-form"
+      name="tform"
+      onSubmit={(e) => {
+        e.preventDefault();
+      }}
+    >
       <p>
         <label for="withdraw-amount">{i18n.str`Amount to withdraw:`}</label>
         &nbsp;
@@ -80,9 +87,10 @@ export function WalletWithdrawForm({
           <input
             id="select-exchange"
             class="pure-button pure-button-primary"
-            type="button"
+            type="submit"
             value={i18n.str`Withdraw`}
-            onClick={() => {
+            onClick={(e) => {
+              e.preventDefault();
               submitAmount = validateAmount(submitAmount);
               /**
                * By invalid amounts, the validator prints error messages
diff --git a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx 
b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
index 8cfdd4e9f..747e8c516 100644
--- a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
+++ b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
@@ -16,7 +16,7 @@
 
 import { Logger } from "@gnu-taler/taler-util";
 import { Fragment, h, VNode } from "preact";
-import { StateUpdater } from "preact/hooks";
+import { StateUpdater, useMemo, useState } from "preact/hooks";
 import { useBackendContext } from "../context/backend.js";
 import { PageStateType, usePageContext } from "../context/pageState.js";
 import {
@@ -36,18 +36,28 @@ export function WithdrawalConfirmationQuestion(): VNode {
   const { pageState, pageStateSetter } = usePageContext();
   const backend = useBackendContext();
   const { i18n } = useTranslationContext();
-  const captchaNumbers = {
-    a: Math.floor(Math.random() * 10),
-    b: Math.floor(Math.random() * 10),
-  };
-  let captchaAnswer = "";
+
+  const captchaNumbers = useMemo(() => {
+    return {
+      a: Math.floor(Math.random() * 10),
+      b: Math.floor(Math.random() * 10),
+    };
+  }, [pageState.withdrawalId]);
+
+  const [captchaAnswer, setCaptchaAnswer] = useState<string | undefined>();
 
   return (
     <Fragment>
       <h1 class="nav">{i18n.str`Confirm Withdrawal`}</h1>
       <article>
         <div class="challenge-div">
-          <form class="challenge-form" noValidate>
+          <form
+            class="challenge-form"
+            noValidate
+            onSubmit={(e) => {
+              e.preventDefault();
+            }}
+          >
             <div class="pure-form" id="captcha" name="capcha-form">
               <h2>{i18n.str`Authorize withdrawal by solving challenge`}</h2>
               <p>
@@ -62,24 +72,26 @@ export function WithdrawalConfirmationQuestion(): VNode {
                 <input
                   name="answer"
                   id="answer"
+                  value={captchaAnswer ?? ""}
                   type="text"
                   autoFocus
                   required
                   onInput={(e): void => {
-                    captchaAnswer = e.currentTarget.value;
+                    setCaptchaAnswer(e.currentTarget.value);
                   }}
                 />
               </p>
               <p>
                 <button
+                  type="submit"
                   class="pure-button pure-button-primary btn-confirm"
-                  onClick={(e) => {
+                  onClick={async (e) => {
                     e.preventDefault();
                     if (
                       captchaAnswer ==
                       (captchaNumbers.a + captchaNumbers.b).toString()
                     ) {
-                      confirmWithdrawalCall(
+                      await confirmWithdrawalCall(
                         backend.state,
                         pageState.withdrawalId,
                         pageStateSetter,
@@ -91,9 +103,10 @@ export function WithdrawalConfirmationQuestion(): VNode {
                       ...prevState,
 
                       error: {
-                        title: i18n.str`Answer is wrong.`,
+                        title: i18n.str`The answer "${captchaAnswer}" to 
"${captchaNumbers.a} + ${captchaNumbers.b}" is wrong.`,
                       },
                     }));
+                    setCaptchaAnswer(undefined);
                   }}
                 >
                   {i18n.str`Confirm`}
@@ -101,14 +114,15 @@ export function WithdrawalConfirmationQuestion(): VNode {
                 &nbsp;
                 <button
                   class="pure-button pure-button-secondary btn-cancel"
-                  onClick={async () =>
+                  onClick={async (e) => {
+                    e.preventDefault();
                     await abortWithdrawalCall(
                       backend.state,
                       pageState.withdrawalId,
                       pageStateSetter,
                       i18n,
-                    )
-                  }
+                    );
+                  }}
                 >
                   {i18n.str`Cancel`}
                 </button>
diff --git a/packages/demobank-ui/src/stories.test.ts 
b/packages/demobank-ui/src/stories.test.ts
index f0b692ed2..a9e5ec5c0 100644
--- a/packages/demobank-ui/src/stories.test.ts
+++ b/packages/demobank-ui/src/stories.test.ts
@@ -24,12 +24,11 @@ import { parseGroupImport } from 
"@gnu-taler/web-util/lib/index.browser";
 import * as pages from "./pages/index.stories.js";
 import * as components from "./components/index.examples.js";
 
-import { h as create } from "preact"
+import { h as create } from "preact";
 import { render as renderToString } from "preact-render-to-string";
 
 setupI18n("en", { en: {} });
 
-
 describe("All the examples:", () => {
   const cms = parseGroupImport({ pages, components });
   cms.forEach((group) => {
@@ -38,8 +37,11 @@ describe("All the examples:", () => {
         describe(`Component ${component.name}:`, () => {
           component.examples.forEach((example) => {
             it(`should render example: ${example.name}`, () => {
-              const vdom = create(example.render.component, 
example.render.props)
-              const html = renderToString(vdom)
+              const vdom = create(
+                example.render.component,
+                example.render.props,
+              );
+              const html = renderToString(vdom);
               // console.log(html)
             });
           });
diff --git a/packages/taler-wallet-webextension/manifest-v2.json 
b/packages/taler-wallet-webextension/manifest-v2.json
index 8c336da25..6adadad98 100644
--- a/packages/taler-wallet-webextension/manifest-v2.json
+++ b/packages/taler-wallet-webextension/manifest-v2.json
@@ -26,6 +26,13 @@
     "https://*/*";,
     "webRequest"
   ],
+  "protocol_handlers": [
+    {
+      "protocol": "ext+taler",
+      "name": "Taler Wallet WebExtension",
+      "uriTemplate": 
"/static/wallet.html#/cta/withdraw?d=1&talerWithdrawUri=%s"
+    }
+  ],
   "browser_action": {
     "default_icon": {
       "16": "static/img/taler-logo-16.png",
diff --git a/packages/taler-wallet-webextension/manifest-v3.json 
b/packages/taler-wallet-webextension/manifest-v3.json
index fe9b75375..4e18125b3 100644
--- a/packages/taler-wallet-webextension/manifest-v3.json
+++ b/packages/taler-wallet-webextension/manifest-v3.json
@@ -29,6 +29,18 @@
   "optional_permissions": [
     "webRequest"
   ],
+  "web_accessible_resources": [
+    {
+      "resources": [
+        "static/wallet.html"
+      ],
+      "matches": [
+        "https://*/*";,
+        "http://*/*";,
+        "file://*/*"
+      ]
+    }
+  ],
   "host_permissions": [
     "http://*/*";,
     "https://*/*";
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts 
b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
index 1ecf05eca..d1853442b 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
@@ -90,7 +90,7 @@ export function useComponentStateFromParams({
 }
 
 export function useComponentStateFromURI({
-  talerWithdrawUri,
+  talerWithdrawUri: maybeTalerUri,
   cancel,
   onSuccess,
 }: PropsFromURI): RecursiveState<State> {
@@ -99,7 +99,10 @@ export function useComponentStateFromURI({
    * Ask the wallet about the withdraw URI
    */
   const uriInfoHook = useAsyncAsHook(async () => {
-    if (!talerWithdrawUri) throw Error("ERROR_NO-URI-FOR-WITHDRAWAL");
+    if (!maybeTalerUri) throw Error("ERROR_NO-URI-FOR-WITHDRAWAL");
+    const talerWithdrawUri = maybeTalerUri.startsWith("ext+")
+      ? maybeTalerUri.substring(4)
+      : maybeTalerUri;
 
     const uriInfo = await api.wallet.call(
       WalletApiOperation.GetWithdrawalDetailsForUri,
diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts 
b/packages/taler-wallet-webextension/src/platform/chrome.ts
index b7b0c6640..744283913 100644
--- a/packages/taler-wallet-webextension/src/platform/chrome.ts
+++ b/packages/taler-wallet-webextension/src/platform/chrome.ts
@@ -233,7 +233,10 @@ function notifyWhenAppIsReady(callback: () => void): void {
   }
 }
 
-function openWalletURIFromPopup(talerUri: string): void {
+function openWalletURIFromPopup(maybeTalerUri: string): void {
+  const talerUri = maybeTalerUri.startsWith("ext+")
+    ? maybeTalerUri.substring(4)
+    : maybeTalerUri;
   const uriType = classifyTalerUri(talerUri);
 
   let url: string | undefined = undefined;
diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx 
b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
index 0916f4f43..4805c03ca 100644
--- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
@@ -170,7 +170,7 @@ export function View({
       <p>
         <i18n.Translate>Debug tools</i18n.Translate>:
       </p>
-      <Grid container justifyContent="space-between" spacing={1}>
+      <Grid container justifyContent="space-between" spacing={1} size={4}>
         <Grid item>
           <Button
             variant="contained"
@@ -251,6 +251,64 @@ export function View({
             <i18n.Translate>export database</i18n.Translate>
           </Button>
         </Grid>
+        <Grid item>
+          <Button
+            variant="contained"
+            onClick={async () => {
+              navigator.registerProtocolHandler(
+                "taler",
+                
`${window.location.origin}/static/wallet.html#/cta/withdraw?talerWithdrawUri=%s`,
+              );
+            }}
+          >
+            <i18n.Translate>Register taler:// handler</i18n.Translate>
+          </Button>
+        </Grid>
+        <Grid item>
+          <Button
+            variant="contained"
+            onClick={async () => {
+              const n = navigator as any;
+              if ("unregisterProtocolHandler" in n) {
+                n.unregisterProtocolHandler(
+                  "taler",
+                  
`${window.location.origin}/static/wallet.html#/cta/withdraw?talerWithdrawUri=%s`,
+                );
+              }
+            }}
+          >
+            <i18n.Translate>Remove taler:// handler</i18n.Translate>
+          </Button>
+        </Grid>{" "}
+        <Grid item>
+          <Button
+            variant="contained"
+            onClick={async () => {
+              navigator.registerProtocolHandler(
+                "ext+taler",
+                
`${window.location.origin}/static/wallet.html#/cta/withdraw?talerWithdrawUri=%s`,
+              );
+            }}
+          >
+            <i18n.Translate>Register ext+taler:// handler</i18n.Translate>
+          </Button>
+        </Grid>
+        <Grid item>
+          <Button
+            variant="contained"
+            onClick={async () => {
+              const n = navigator as any;
+              if ("unregisterProtocolHandler" in n) {
+                n.unregisterProtocolHandler(
+                  "ext+taler",
+                  
`${window.location.origin}/static/wallet.html#/cta/withdraw?talerWithdrawUri=%s`,
+                );
+              }
+            }}
+          >
+            <i18n.Translate>Remove ext+taler:// handler</i18n.Translate>
+          </Button>
+        </Grid>{" "}
       </Grid>
       {downloadedDatabase && (
         <div>
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts 
b/packages/taler-wallet-webextension/src/wxBackend.ts
index dca239de6..0f0beb41f 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -298,7 +298,10 @@ async function reinitWallet(): Promise<void> {
   return walletInit.resolve();
 }
 
-function parseTalerUriAndRedirect(tabId: number, talerUri: string): void {
+function parseTalerUriAndRedirect(tabId: number, maybeTalerUri: string): void {
+  const talerUri = maybeTalerUri.startsWith("ext+")
+    ? maybeTalerUri.substring(4)
+    : maybeTalerUri;
   const uriType = classifyTalerUri(talerUri);
   switch (uriType) {
     case TalerUriType.TalerWithdraw:

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]