gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: prettier


From: gnunet
Subject: [taler-wallet-core] branch master updated: prettier
Date: Mon, 15 Nov 2021 15:19:07 +0100

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

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

The following commit(s) were added to refs/heads/master by this push:
     new 1d4815c6 prettier
1d4815c6 is described below

commit 1d4815c66c395f4fcc86c30e20f3d005e3cb9ff5
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Mon Nov 15 11:18:58 2021 -0300

    prettier
---
 packages/taler-wallet-webextension/package.json    |   3 +-
 .../src/NavigationBar.tsx                          |  75 +--
 .../src/browserCryptoWorkerFactory.js              |  35 +-
 .../src/browserCryptoWorkerFactory.ts              |   5 +-
 packages/taler-wallet-webextension/src/compat.js   |  57 ++-
 .../src/components/Checkbox.tsx                    |  33 +-
 .../src/components/CheckboxOutlined.tsx            |  47 +-
 .../src/components/DebugCheckbox.tsx               |  13 +-
 .../src/components/Diagnostics.tsx                 |  12 +-
 .../src/components/EditableText.tsx                |  66 ++-
 .../src/components/ErrorMessage.tsx                |  41 +-
 .../src/components/ExchangeToS.tsx                 |  86 ++--
 .../src/components/LogoHeader.tsx                  |  31 +-
 .../src/components/Part.tsx                        |  28 +-
 .../src/components/QR.tsx                          |  53 +-
 .../src/components/SelectList.tsx                  |  95 ++--
 .../src/components/TransactionItem.tsx             |  76 ++-
 .../src/components/styled/index.tsx                | 219 ++++-----
 .../src/context/devContext.ts                      |  24 +-
 .../src/context/translation.ts                     |  56 ++-
 .../src/cta/Pay.stories.tsx                        | 190 ++++----
 packages/taler-wallet-webextension/src/cta/Pay.tsx | 351 ++++++++-----
 .../src/cta/Refund.stories.tsx                     |  72 ++-
 .../taler-wallet-webextension/src/cta/Refund.tsx   |  53 +-
 .../src/cta/Tip.stories.tsx                        |  48 +-
 packages/taler-wallet-webextension/src/cta/Tip.tsx |  44 +-
 .../src/cta/Withdraw.stories.tsx                   | 542 +++++++++++----------
 .../taler-wallet-webextension/src/cta/Withdraw.tsx | 500 ++++++++++++-------
 .../taler-wallet-webextension/src/cta/payback.tsx  |   2 +-
 .../src/cta/reset-required.tsx                     |   2 +-
 .../src/cta/return-coins.tsx                       |   2 +-
 packages/taler-wallet-webextension/src/custom.d.ts |   2 +-
 .../src/hooks/useAsyncAsHook.ts                    |   4 +-
 .../src/hooks/useBackupDeviceName.ts               |  25 +-
 .../src/hooks/useBackupStatus.ts                   |  50 +-
 .../src/hooks/useBalances.ts                       |   3 +-
 .../src/hooks/useDiagnostics.ts                    |   6 +-
 .../src/hooks/useExtendedPermissions.ts            |   9 +-
 .../taler-wallet-webextension/src/hooks/useLang.ts |  13 +-
 .../src/hooks/useLocalStorage.ts                   |  44 +-
 .../src/hooks/useProviderStatus.ts                 |   4 +-
 .../src/hooks/useTalerActionURL.ts                 |   9 +-
 .../taler-wallet-webextension/src/i18n/strings.ts  |   2 +-
 .../src/popup/Backup.stories.tsx                   | 307 ++++++------
 .../src/popup/BackupPage.tsx                       | 176 ++++---
 .../src/popup/Balance.stories.tsx                  | 253 +++++-----
 .../src/popup/BalancePage.tsx                      | 219 +++++----
 .../taler-wallet-webextension/src/popup/Debug.tsx  |   8 +-
 .../src/popup/History.stories.tsx                  | 184 +++----
 .../src/popup/History.tsx                          | 122 +++--
 .../src/popup/Popup.stories.tsx                    |  29 +-
 .../popup/ProviderAddConfirmProvider.stories.tsx   |  41 +-
 .../src/popup/ProviderAddSetUrl.stories.tsx        |  40 +-
 .../src/popup/ProviderDetail.stories.tsx           | 323 ++++++------
 .../src/popup/ProviderDetailPage.tsx               | 269 ++++++----
 .../src/popup/Settings.stories.tsx                 |  19 +-
 .../src/popup/Settings.tsx                         |  93 ++--
 .../src/popup/TalerActionFound.stories.tsx         |  24 +-
 .../src/popup/TalerActionFound.tsx                 | 161 ++++--
 .../src/popupEntryPoint.tsx                        |  77 +--
 .../taler-wallet-webextension/src/renderHtml.tsx   |  38 +-
 .../taler-wallet-webextension/src/test-utils.ts    |  16 +-
 .../src/wallet/Backup.stories.tsx                  | 307 ++++++------
 .../src/wallet/BackupPage.tsx                      | 177 ++++---
 .../src/wallet/Balance.stories.tsx                 |  84 ++--
 .../src/wallet/BalancePage.tsx                     | 129 +++--
 .../src/wallet/CreateManualWithdraw.stories.tsx    |  39 +-
 .../src/wallet/CreateManualWithdraw.tsx            |  94 +++-
 .../src/wallet/History.stories.tsx                 | 198 ++++----
 .../src/wallet/History.tsx                         | 103 ++--
 .../src/wallet/ManualWithdrawPage.tsx              |  92 ++--
 .../wallet/ProviderAddConfirmProvider.stories.tsx  |  41 +-
 .../src/wallet/ProviderAddSetUrl.stories.tsx       |  40 +-
 .../src/wallet/ProviderDetail.stories.tsx          | 323 ++++++------
 .../src/wallet/ProviderDetailPage.tsx              | 269 ++++++----
 .../src/wallet/ReserveCreated.stories.tsx          |  25 +-
 .../src/wallet/ReserveCreated.tsx                  |  54 +-
 .../src/wallet/Settings.stories.tsx                |  32 +-
 .../src/wallet/Settings.tsx                        | 109 +++--
 .../src/wallet/Transaction.stories.tsx             | 213 ++++----
 .../src/wallet/Transaction.tsx                     | 442 +++++++++++------
 .../src/wallet/Welcome.stories.tsx                 |  20 +-
 .../src/wallet/Welcome.tsx                         |  76 +--
 .../src/walletEntryPoint.tsx                       | 128 +++--
 packages/taler-wallet-webextension/src/wxApi.ts    | 104 ++--
 packages/taler-wallet-webextension/tsconfig.json   |  20 +-
 86 files changed, 4970 insertions(+), 3580 deletions(-)

diff --git a/packages/taler-wallet-webextension/package.json 
b/packages/taler-wallet-webextension/package.json
index 3a43f1e7..b3d0b10a 100644
--- a/packages/taler-wallet-webextension/package.json
+++ b/packages/taler-wallet-webextension/package.json
@@ -13,6 +13,7 @@
     "compile": "tsc && rollup -c",
     "build-storybook": "build-storybook",
     "storybook": "start-storybook -s . -p 6006",
+    "pretty": "prettier --write src",
     "watch": "tsc --watch & rollup -w -c"
   },
   "dependencies": {
@@ -80,4 +81,4 @@
       
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|po)$":
 "<rootDir>/tests/__mocks__/fileTransformer.js"
     }
   }
-}
+}
\ No newline at end of file
diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx 
b/packages/taler-wallet-webextension/src/NavigationBar.tsx
index 9edd8ca6..f206fa2d 100644
--- a/packages/taler-wallet-webextension/src/NavigationBar.tsx
+++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx
@@ -28,29 +28,29 @@ import { i18n } from "@gnu-taler/taler-util";
 import { ComponentChildren, JSX, h } from "preact";
 import Match from "preact-router/match";
 import { useDevContext } from "./context/devContext";
-import { PopupNavigation } from './components/styled'
+import { PopupNavigation } from "./components/styled";
 
 export enum Pages {
-  welcome = '/welcome',
-  balance = '/balance',
-  manual_withdraw = '/manual-withdraw',
-  settings = '/settings',
-  dev = '/dev',
-  cta = '/cta',
-  backup = '/backup',
-  history = '/history',
-  transaction = '/transaction/:tid',
-  provider_detail = '/provider/:pid',
-  provider_add = '/provider/add',
+  welcome = "/welcome",
+  balance = "/balance",
+  manual_withdraw = "/manual-withdraw",
+  settings = "/settings",
+  dev = "/dev",
+  cta = "/cta",
+  backup = "/backup",
+  history = "/history",
+  transaction = "/transaction/:tid",
+  provider_detail = "/provider/:pid",
+  provider_add = "/provider/add",
 
-  reset_required = '/reset-required',
-  payback = '/payback',
-  return_coins = '/return-coins',
+  reset_required = "/reset-required",
+  payback = "/payback",
+  return_coins = "/return-coins",
 
-  pay = '/pay',
-  refund = '/refund',
-  tips = '/tip',
-  withdraw = '/withdraw',
+  pay = "/pay",
+  refund = "/refund",
+  tips = "/tip",
+  withdraw = "/withdraw",
 }
 
 interface TabProps {
@@ -71,23 +71,28 @@ function Tab(props: TabProps): JSX.Element {
   );
 }
 
-export function NavBar({ devMode, path }: { path: string, devMode: boolean }) {
-  return <PopupNavigation devMode={devMode}>
-    <div>
-      <Tab target="/balance" current={path}>{i18n.str`Balance`}</Tab>
-      <Tab target="/history" current={path}>{i18n.str`History`}</Tab>
-      <Tab target="/backup" current={path}>{i18n.str`Backup`}</Tab>
-      <Tab target="/settings" current={path}>{i18n.str`Settings`}</Tab>
-      {devMode && <Tab target="/dev" current={path}>{i18n.str`Dev`}</Tab>}
-    </div>
-  </PopupNavigation>
+export function NavBar({ devMode, path }: { path: string; devMode: boolean }) {
+  return (
+    <PopupNavigation devMode={devMode}>
+      <div>
+        <Tab target="/balance" current={path}>{i18n.str`Balance`}</Tab>
+        <Tab target="/history" current={path}>{i18n.str`History`}</Tab>
+        <Tab target="/backup" current={path}>{i18n.str`Backup`}</Tab>
+        <Tab target="/settings" current={path}>{i18n.str`Settings`}</Tab>
+        {devMode && <Tab target="/dev" current={path}>{i18n.str`Dev`}</Tab>}
+      </div>
+    </PopupNavigation>
+  );
 }
 
 export function WalletNavBar() {
-  const { devMode } = useDevContext()
-  return <Match>{({ path }: any) => {
-    console.log("path", path)
-    return <NavBar devMode={devMode} path={path} />
-  }}</Match>
+  const { devMode } = useDevContext();
+  return (
+    <Match>
+      {({ path }: any) => {
+        console.log("path", path);
+        return <NavBar devMode={devMode} path={path} />;
+      }}
+    </Match>
+  );
 }
-
diff --git 
a/packages/taler-wallet-webextension/src/browserCryptoWorkerFactory.js 
b/packages/taler-wallet-webextension/src/browserCryptoWorkerFactory.js
index e9492a2f..8d958d6b 100644
--- a/packages/taler-wallet-webextension/src/browserCryptoWorkerFactory.js
+++ b/packages/taler-wallet-webextension/src/browserCryptoWorkerFactory.js
@@ -21,24 +21,23 @@ exports.BrowserCryptoWorkerFactory = void 0;
  * @author Florian Dold
  */
 class BrowserCryptoWorkerFactory {
-    startWorker() {
-        const workerCtor = Worker;
-        const workerPath = "/browserWorkerEntry.js";
-        return new workerCtor(workerPath);
-    }
-    getConcurrency() {
-        let concurrency = 2;
-        try {
-            // only works in the browser
-            // tslint:disable-next-line:no-string-literal
-            concurrency = navigator["hardwareConcurrency"];
-            concurrency = Math.max(1, Math.ceil(concurrency / 2));
-        }
-        catch (e) {
-            concurrency = 2;
-        }
-        return concurrency;
+  startWorker() {
+    const workerCtor = Worker;
+    const workerPath = "/browserWorkerEntry.js";
+    return new workerCtor(workerPath);
+  }
+  getConcurrency() {
+    let concurrency = 2;
+    try {
+      // only works in the browser
+      // tslint:disable-next-line:no-string-literal
+      concurrency = navigator["hardwareConcurrency"];
+      concurrency = Math.max(1, Math.ceil(concurrency / 2));
+    } catch (e) {
+      concurrency = 2;
     }
+    return concurrency;
+  }
 }
 exports.BrowserCryptoWorkerFactory = BrowserCryptoWorkerFactory;
-//# sourceMappingURL=browserCryptoWorkerFactory.js.map
\ No newline at end of file
+//# sourceMappingURL=browserCryptoWorkerFactory.js.map
diff --git 
a/packages/taler-wallet-webextension/src/browserCryptoWorkerFactory.ts 
b/packages/taler-wallet-webextension/src/browserCryptoWorkerFactory.ts
index a8315dc6..ab20228e 100644
--- a/packages/taler-wallet-webextension/src/browserCryptoWorkerFactory.ts
+++ b/packages/taler-wallet-webextension/src/browserCryptoWorkerFactory.ts
@@ -19,7 +19,10 @@
  * @author Florian Dold
  */
 
-import type { CryptoWorker, CryptoWorkerFactory } from 
"@gnu-taler/taler-wallet-core";
+import type {
+  CryptoWorker,
+  CryptoWorkerFactory,
+} from "@gnu-taler/taler-wallet-core";
 
 export class BrowserCryptoWorkerFactory implements CryptoWorkerFactory {
   startWorker(): CryptoWorker {
diff --git a/packages/taler-wallet-webextension/src/compat.js 
b/packages/taler-wallet-webextension/src/compat.js
index fdfcbd4b..48e49a0a 100644
--- a/packages/taler-wallet-webextension/src/compat.js
+++ b/packages/taler-wallet-webextension/src/compat.js
@@ -21,41 +21,44 @@ exports.getPermissionsApi = exports.isNode = 
exports.isFirefox = void 0;
  * WebExtension APIs consistently.
  */
 function isFirefox() {
-    const rt = chrome.runtime;
-    if (typeof rt.getBrowserInfo === "function") {
-        return true;
-    }
-    return false;
+  const rt = chrome.runtime;
+  if (typeof rt.getBrowserInfo === "function") {
+    return true;
+  }
+  return false;
 }
 exports.isFirefox = isFirefox;
 /**
  * Check if we are running under nodejs.
  */
 function isNode() {
-    return typeof process !== "undefined" && process.release.name === "node";
+  return typeof process !== "undefined" && process.release.name === "node";
 }
 exports.isNode = isNode;
 function getPermissionsApi() {
-    const myBrowser = globalThis.browser;
-    if (typeof myBrowser === "object" &&
-        typeof myBrowser.permissions === "object") {
-        return {
-            addPermissionsListener: () => {
-                // Not supported yet.
-            },
-            contains: myBrowser.permissions.contains,
-            request: myBrowser.permissions.request,
-            remove: myBrowser.permissions.remove,
-        };
-    }
-    else {
-        return {
-            addPermissionsListener: 
chrome.permissions.onAdded.addListener.bind(chrome.permissions.onAdded),
-            contains: chrome.permissions.contains,
-            request: chrome.permissions.request,
-            remove: chrome.permissions.remove,
-        };
-    }
+  const myBrowser = globalThis.browser;
+  if (
+    typeof myBrowser === "object" &&
+    typeof myBrowser.permissions === "object"
+  ) {
+    return {
+      addPermissionsListener: () => {
+        // Not supported yet.
+      },
+      contains: myBrowser.permissions.contains,
+      request: myBrowser.permissions.request,
+      remove: myBrowser.permissions.remove,
+    };
+  } else {
+    return {
+      addPermissionsListener: chrome.permissions.onAdded.addListener.bind(
+        chrome.permissions.onAdded,
+      ),
+      contains: chrome.permissions.contains,
+      request: chrome.permissions.request,
+      remove: chrome.permissions.remove,
+    };
+  }
 }
 exports.getPermissionsApi = getPermissionsApi;
-//# sourceMappingURL=compat.js.map
\ No newline at end of file
+//# sourceMappingURL=compat.js.map
diff --git a/packages/taler-wallet-webextension/src/components/Checkbox.tsx 
b/packages/taler-wallet-webextension/src/components/Checkbox.tsx
index 2d7b9808..276ac9ff 100644
--- a/packages/taler-wallet-webextension/src/components/Checkbox.tsx
+++ b/packages/taler-wallet-webextension/src/components/Checkbox.tsx
@@ -24,7 +24,13 @@ interface Props {
   name: string;
   description?: string;
 }
-export function Checkbox({ name, enabled, onToggle, label, description }: 
Props): JSX.Element {
+export function Checkbox({
+  name,
+  enabled,
+  onToggle,
+  label,
+  description,
+}: Props): JSX.Element {
   return (
     <div>
       <input
@@ -32,23 +38,26 @@ export function Checkbox({ name, enabled, onToggle, label, 
description }: Props)
         onClick={onToggle}
         type="checkbox"
         id={`checkbox-${name}`}
-        style={{ width: "1.5em", height: "1.5em", verticalAlign: "middle" }} />
+        style={{ width: "1.5em", height: "1.5em", verticalAlign: "middle" }}
+      />
       <label
         htmlFor={`checkbox-${name}`}
         style={{ marginLeft: "0.5em", fontWeight: "bold" }}
       >
         {label}
       </label>
-      {description && <span
-        style={{
-          color: "#383838",
-          fontSize: "smaller",
-          display: "block",
-          marginLeft: "2em",
-        }}
-      >
-        {description}
-      </span>}
+      {description && (
+        <span
+          style={{
+            color: "#383838",
+            fontSize: "smaller",
+            display: "block",
+            marginLeft: "2em",
+          }}
+        >
+          {description}
+        </span>
+      )}
     </div>
   );
 }
diff --git 
a/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx 
b/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx
index 5e30ee3d..2fc8316f 100644
--- a/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx
+++ b/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx
@@ -16,7 +16,7 @@
 
 import { JSX } from "preact/jsx-runtime";
 import { Outlined, StyledCheckboxLabel } from "./styled/index";
-import { h } from 'preact';
+import { h } from "preact";
 
 interface Props {
   enabled: boolean;
@@ -25,28 +25,39 @@ interface Props {
   name: string;
 }
 
+const Tick = () => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg";
+    viewBox="0 0 24 24"
+    aria-hidden="true"
+    focusable="false"
+    style={{ backgroundColor: "green" }}
+  >
+    <path
+      fill="none"
+      stroke="white"
+      stroke-width="3"
+      d="M1.73 12.91l6.37 6.37L22.79 4.59"
+    />
+  </svg>
+);
 
-const Tick = () => <svg
-  xmlns="http://www.w3.org/2000/svg";
-  viewBox="0 0 24 24"
-  aria-hidden="true"
-  focusable="false"
-  style={{ backgroundColor: 'green' }}
->
-  <path
-    fill="none"
-    stroke="white"
-    stroke-width="3"
-    d="M1.73 12.91l6.37 6.37L22.79 4.59"
-  />
-</svg>
-
-export function CheckboxOutlined({ name, enabled, onToggle, label }: Props): 
JSX.Element {
+export function CheckboxOutlined({
+  name,
+  enabled,
+  onToggle,
+  label,
+}: Props): JSX.Element {
   return (
     <Outlined>
       <StyledCheckboxLabel onClick={onToggle}>
         <span>
-          <input type="checkbox" name={name} checked={enabled} 
disabled={false} />
+          <input
+            type="checkbox"
+            name={name}
+            checked={enabled}
+            disabled={false}
+          />
           <div>
             <Tick />
           </div>
diff --git 
a/packages/taler-wallet-webextension/src/components/DebugCheckbox.tsx 
b/packages/taler-wallet-webextension/src/components/DebugCheckbox.tsx
index f0c682cc..952df15a 100644
--- a/packages/taler-wallet-webextension/src/components/DebugCheckbox.tsx
+++ b/packages/taler-wallet-webextension/src/components/DebugCheckbox.tsx
@@ -14,9 +14,15 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
- import { JSX, h } from "preact";
+import { JSX, h } from "preact";
 
-export function DebugCheckbox({ enabled, onToggle }: { enabled: boolean; 
onToggle: () => void; }): JSX.Element {
+export function DebugCheckbox({
+  enabled,
+  onToggle,
+}: {
+  enabled: boolean;
+  onToggle: () => void;
+}): JSX.Element {
   return (
     <div>
       <input
@@ -24,7 +30,8 @@ export function DebugCheckbox({ enabled, onToggle }: { 
enabled: boolean; onToggl
         onClick={onToggle}
         type="checkbox"
         id="checkbox-perm"
-        style={{ width: "1.5em", height: "1.5em", verticalAlign: "middle" }} />
+        style={{ width: "1.5em", height: "1.5em", verticalAlign: "middle" }}
+      />
       <label
         htmlFor="checkbox-perm"
         style={{ marginLeft: "0.5em", fontWeight: "bold" }}
diff --git a/packages/taler-wallet-webextension/src/components/Diagnostics.tsx 
b/packages/taler-wallet-webextension/src/components/Diagnostics.tsx
index b48deb84..0f8afd52 100644
--- a/packages/taler-wallet-webextension/src/components/Diagnostics.tsx
+++ b/packages/taler-wallet-webextension/src/components/Diagnostics.tsx
@@ -21,11 +21,13 @@ import { PageLink } from "../renderHtml";
 
 interface Props {
   timedOut: boolean;
-  diagnostics: WalletDiagnostics | undefined
+  diagnostics: WalletDiagnostics | undefined;
 }
 
-export function Diagnostics({timedOut, diagnostics}: Props): JSX.Element | 
null {
-
+export function Diagnostics({
+  timedOut,
+  diagnostics,
+}: Props): JSX.Element | null {
   if (timedOut) {
     return <p>Diagnostics timed out. Could not talk to the wallet backend.</p>;
   }
@@ -60,8 +62,8 @@ export function Diagnostics({timedOut, diagnostics}: Props): 
JSX.Element | null
             <p>
               Your wallet database is outdated. Currently automatic migration 
is
               not supported. Please go{" "}
-              <PageLink pageName="/reset-required">here</PageLink> to reset
-              the wallet database.
+              <PageLink pageName="/reset-required">here</PageLink> to reset the
+              wallet database.
             </p>
           ) : null}
         </div>
diff --git a/packages/taler-wallet-webextension/src/components/EditableText.tsx 
b/packages/taler-wallet-webextension/src/components/EditableText.tsx
index 6f3388bf..8b3e6d37 100644
--- a/packages/taler-wallet-webextension/src/components/EditableText.tsx
+++ b/packages/taler-wallet-webextension/src/components/EditableText.tsx
@@ -25,25 +25,37 @@ interface Props {
   name: string;
   description?: string;
 }
-export function EditableText({ name, value, onChange, label, description }: 
Props): JSX.Element {
-  const [editing, setEditing] = useState(false)
-  const ref = useRef<HTMLInputElement>(null)
+export function EditableText({
+  name,
+  value,
+  onChange,
+  label,
+  description,
+}: Props): JSX.Element {
+  const [editing, setEditing] = useState(false);
+  const ref = useRef<HTMLInputElement>(null);
   let InputText;
   if (!editing) {
-    InputText = () => <div style={{ display: 'flex', justifyContent: 
'space-between' }}>
-      <p>{value}</p>
-      <button onClick={() => setEditing(true)}>edit</button>
-    </div>
+    InputText = () => (
+      <div style={{ display: "flex", justifyContent: "space-between" }}>
+        <p>{value}</p>
+        <button onClick={() => setEditing(true)}>edit</button>
+      </div>
+    );
   } else {
-    InputText = () => <div style={{ display: 'flex', justifyContent: 
'space-between' }}>
-      <input
-        value={value}
-        ref={ref}
-        type="text"
-        id={`text-${name}`}
-      />
-      <button onClick={() => { if (ref.current) 
onChange(ref.current.value).then(r => setEditing(false)) }}>confirm</button>
-    </div>
+    InputText = () => (
+      <div style={{ display: "flex", justifyContent: "space-between" }}>
+        <input value={value} ref={ref} type="text" id={`text-${name}`} />
+        <button
+          onClick={() => {
+            if (ref.current)
+              onChange(ref.current.value).then((r) => setEditing(false));
+          }}
+        >
+          confirm
+        </button>
+      </div>
+    );
   }
   return (
     <div>
@@ -54,16 +66,18 @@ export function EditableText({ name, value, onChange, 
label, description }: Prop
         {label}
       </label>
       <InputText />
-      {description && <span
-        style={{
-          color: "#383838",
-          fontSize: "smaller",
-          display: "block",
-          marginLeft: "2em",
-        }}
-      >
-        {description}
-      </span>}
+      {description && (
+        <span
+          style={{
+            color: "#383838",
+            fontSize: "smaller",
+            display: "block",
+            marginLeft: "2em",
+          }}
+        >
+          {description}
+        </span>
+      )}
     </div>
   );
 }
diff --git a/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx 
b/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx
index cfcef16d..c6b64fb6 100644
--- a/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx
+++ b/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx
@@ -13,22 +13,35 @@
  You should have received a copy of the GNU General Public License along with
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
- import { VNode, h } from "preact";
+import { VNode, h } from "preact";
 import { useState } from "preact/hooks";
-import arrowDown from '../../static/img/chevron-down.svg';
+import arrowDown from "../../static/img/chevron-down.svg";
 import { ErrorBox } from "./styled";
 
-export function ErrorMessage({ title, description }: { title?: string|VNode; 
description?: string; }) {
+export function ErrorMessage({
+  title,
+  description,
+}: {
+  title?: string | VNode;
+  description?: string;
+}) {
   const [showErrorDetail, setShowErrorDetail] = useState(false);
-  if (!title)
-    return null;
-  return <ErrorBox style={{paddingTop: 0, paddingBottom: 0}}>
-    <div>
-      <p>{title}</p>
-      { description && <button onClick={() => { setShowErrorDetail(v => !v); 
}}>
-        <img style={{ height: '1.5em' }} src={arrowDown} />
-      </button> }
-    </div>
-    {showErrorDetail && <p>{description}</p>}
-  </ErrorBox>;
+  if (!title) return null;
+  return (
+    <ErrorBox style={{ paddingTop: 0, paddingBottom: 0 }}>
+      <div>
+        <p>{title}</p>
+        {description && (
+          <button
+            onClick={() => {
+              setShowErrorDetail((v) => !v);
+            }}
+          >
+            <img style={{ height: "1.5em" }} src={arrowDown} />
+          </button>
+        )}
+      </div>
+      {showErrorDetail && <p>{description}</p>}
+    </ErrorBox>
+  );
 }
diff --git a/packages/taler-wallet-webextension/src/components/ExchangeToS.tsx 
b/packages/taler-wallet-webextension/src/components/ExchangeToS.tsx
index cfa20280..6d2731cd 100644
--- a/packages/taler-wallet-webextension/src/components/ExchangeToS.tsx
+++ b/packages/taler-wallet-webextension/src/components/ExchangeToS.tsx
@@ -13,66 +13,80 @@
  You should have received a copy of the GNU General Public License along with
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
- import { Fragment, VNode } from "preact"
-import { useState } from "preact/hooks"
-import { JSXInternal } from "preact/src/jsx"
-import { h } from 'preact';
+import { Fragment, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { JSXInternal } from "preact/src/jsx";
+import { h } from "preact";
 
 export function ExchangeXmlTos({ doc }: { doc: Document }) {
-  const termsNode = doc.querySelector('[ids=terms-of-service]')
+  const termsNode = doc.querySelector("[ids=terms-of-service]");
   if (!termsNode) {
-    return <div>
-      <p>The exchange send us an xml but there is no node with 
'ids=terms-of-service'. This is the content:</p>
-      <pre>{new XMLSerializer().serializeToString(doc)}</pre>
-    </div>
+    return (
+      <div>
+        <p>
+          The exchange send us an xml but there is no node with
+          'ids=terms-of-service'. This is the content:
+        </p>
+        <pre>{new XMLSerializer().serializeToString(doc)}</pre>
+      </div>
+    );
   }
-  return <Fragment>
-    {Array.from(termsNode.children).map(renderChild)}
-  </Fragment>
+  return 
<Fragment>{Array.from(termsNode.children).map(renderChild)}</Fragment>;
 }
 
 /**
  * Map XML elements into HTML
- * @param child 
- * @returns 
+ * @param child
+ * @returns
  */
 function renderChild(child: Element): VNode {
-  const children = Array.from(child.children)
+  const children = Array.from(child.children);
   switch (child.nodeName) {
-    case 'title': return <header>{child.textContent}</header>
-    case '#text': return <Fragment />
-    case 'paragraph': return <p>{child.textContent}</p>
-    case 'section': {
-      return <AnchorWithOpenState href={`#terms-${child.getAttribute('ids')}`}>
-        {children.map(renderChild)}
-      </AnchorWithOpenState>
+    case "title":
+      return <header>{child.textContent}</header>;
+    case "#text":
+      return <Fragment />;
+    case "paragraph":
+      return <p>{child.textContent}</p>;
+    case "section": {
+      return (
+        <AnchorWithOpenState href={`#terms-${child.getAttribute("ids")}`}>
+          {children.map(renderChild)}
+        </AnchorWithOpenState>
+      );
     }
-    case 'bullet_list': {
-      return <ul>{children.map(renderChild)}</ul>
+    case "bullet_list": {
+      return <ul>{children.map(renderChild)}</ul>;
     }
-    case 'enumerated_list': {
-      return <ol>{children.map(renderChild)}</ol>
+    case "enumerated_list": {
+      return <ol>{children.map(renderChild)}</ol>;
     }
-    case 'list_item': {
-      return <li>{children.map(renderChild)}</li>
+    case "list_item": {
+      return <li>{children.map(renderChild)}</li>;
     }
-    case 'block_quote': {
-      return <div>{children.map(renderChild)}</div>
+    case "block_quote": {
+      return <div>{children.map(renderChild)}</div>;
     }
-    default: return <div style={{ color: 'red', display: 'hidden' }}>unknown 
tag {child.nodeName} <a></a></div>
+    default:
+      return (
+        <div style={{ color: "red", display: "hidden" }}>
+          unknown tag {child.nodeName} <a></a>
+        </div>
+      );
   }
 }
 
 /**
  * Simple anchor with a state persisted into 'data-open' prop
- * @returns 
+ * @returns
  */
-function AnchorWithOpenState(props: 
JSXInternal.HTMLAttributes<HTMLAnchorElement>) {
-  const [open, setOpen] = useState<boolean>(false)
+function AnchorWithOpenState(
+  props: JSXInternal.HTMLAttributes<HTMLAnchorElement>,
+) {
+  const [open, setOpen] = useState<boolean>(false);
   function doClick(e: JSXInternal.TargetedMouseEvent<HTMLAnchorElement>) {
     setOpen(!open);
     e.preventDefault();
   }
-  return <a data-open={open ? 'true' : 'false'} onClick={doClick} {...props} />
+  return <a data-open={open ? "true" : "false"} onClick={doClick} {...props} 
/>;
 }
-
diff --git a/packages/taler-wallet-webextension/src/components/LogoHeader.tsx 
b/packages/taler-wallet-webextension/src/components/LogoHeader.tsx
index 9b75c62a..6c47dc92 100644
--- a/packages/taler-wallet-webextension/src/components/LogoHeader.tsx
+++ b/packages/taler-wallet-webextension/src/components/LogoHeader.tsx
@@ -17,15 +17,22 @@
 import { h } from "preact";
 
 export function LogoHeader() {
-  return <div style={{
-    display: 'flex',
-    justifyContent: 'space-around',
-    margin: '2em',
-  }}>
-    <img style={{
-      width: 150,
-      height: 70,
-    }} src="/static/img/logo-2021.svg" width="150" />
-  </div>
-
-}
\ No newline at end of file
+  return (
+    <div
+      style={{
+        display: "flex",
+        justifyContent: "space-around",
+        margin: "2em",
+      }}
+    >
+      <img
+        style={{
+          width: 150,
+          height: 70,
+        }}
+        src="/static/img/logo-2021.svg"
+        width="150"
+      />
+    </div>
+  );
+}
diff --git a/packages/taler-wallet-webextension/src/components/Part.tsx 
b/packages/taler-wallet-webextension/src/components/Part.tsx
index 75c9df16..c8ecb46d 100644
--- a/packages/taler-wallet-webextension/src/components/Part.tsx
+++ b/packages/taler-wallet-webextension/src/components/Part.tsx
@@ -15,18 +15,28 @@
  */
 import { AmountLike } from "@gnu-taler/taler-util";
 import { ExtraLargeText, LargeText, SmallLightText } from "./styled";
-import { h } from 'preact';
+import { h } from "preact";
 
-export type Kind = 'positive' | 'negative' | 'neutral';
+export type Kind = "positive" | "negative" | "neutral";
 interface Props {
-  title: string, text: AmountLike, kind: Kind, big?: boolean
+  title: string;
+  text: AmountLike;
+  kind: Kind;
+  big?: boolean;
 }
 export function Part({ text, title, kind, big }: Props) {
   const Text = big ? ExtraLargeText : LargeText;
-  return <div style={{ margin: '1em' }}>
-    <SmallLightText style={{ margin: '.5em' }}>{title}</SmallLightText>
-    <Text style={{ color: kind == 'positive' ? 'green' : (kind == 'negative' ? 
'red' : 'black') }}>
-      {text}
-    </Text>
-  </div>
+  return (
+    <div style={{ margin: "1em" }}>
+      <SmallLightText style={{ margin: ".5em" }}>{title}</SmallLightText>
+      <Text
+        style={{
+          color:
+            kind == "positive" ? "green" : kind == "negative" ? "red" : 
"black",
+        }}
+      >
+        {text}
+      </Text>
+    </div>
+  );
 }
diff --git a/packages/taler-wallet-webextension/src/components/QR.tsx 
b/packages/taler-wallet-webextension/src/components/QR.tsx
index 8e3f6929..4ff1af96 100644
--- a/packages/taler-wallet-webextension/src/components/QR.tsx
+++ b/packages/taler-wallet-webextension/src/components/QR.tsx
@@ -14,24 +14,35 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
- import { h, VNode } from "preact";
- import { useEffect, useRef } from "preact/hooks";
- import qrcode from "qrcode-generator";
- 
- export function QR({ text }: { text: string; }):VNode {
-   const divRef = useRef<HTMLDivElement>(null);
-   useEffect(() => {
-     if (!divRef.current) return
-     const qr = qrcode(0, 'L');
-     qr.addData(text);
-     qr.make();
-     divRef.current.innerHTML = qr.createSvgTag({
-       scalable: true,
-     });
-   });
- 
-   return <div style={{ width: '100%', display: 'flex', flexDirection: 
'column', alignItems: 'center' }}>
-     <div style={{ width: '50%', minWidth: 200, maxWidth: 300 }} ref={divRef} 
/>
-   </div>;
- }
- 
\ No newline at end of file
+import { h, VNode } from "preact";
+import { useEffect, useRef } from "preact/hooks";
+import qrcode from "qrcode-generator";
+
+export function QR({ text }: { text: string }): VNode {
+  const divRef = useRef<HTMLDivElement>(null);
+  useEffect(() => {
+    if (!divRef.current) return;
+    const qr = qrcode(0, "L");
+    qr.addData(text);
+    qr.make();
+    divRef.current.innerHTML = qr.createSvgTag({
+      scalable: true,
+    });
+  });
+
+  return (
+    <div
+      style={{
+        width: "100%",
+        display: "flex",
+        flexDirection: "column",
+        alignItems: "center",
+      }}
+    >
+      <div
+        style={{ width: "50%", minWidth: 200, maxWidth: 300 }}
+        ref={divRef}
+      />
+    </div>
+  );
+}
diff --git a/packages/taler-wallet-webextension/src/components/SelectList.tsx 
b/packages/taler-wallet-webextension/src/components/SelectList.tsx
index 536e5b89..f89ba19b 100644
--- a/packages/taler-wallet-webextension/src/components/SelectList.tsx
+++ b/packages/taler-wallet-webextension/src/components/SelectList.tsx
@@ -23,46 +23,67 @@ interface Props {
   onChange: (s: string) => void;
   label: string;
   list: {
-    [label: string]: string
-  }
+    [label: string]: string;
+  };
   name: string;
   description?: string;
   canBeNull?: boolean;
 }
 
-export function SelectList({ name, value, list, canBeNull, onChange, label, 
description }: Props): JSX.Element {
-  return <div>
-    <label
-      htmlFor={`text-${name}`}
-      style={{ marginLeft: "0.5em", fontWeight: "bold" }}
-    > {label}</label>
-    <NiceSelect>
-      <select name={name} onChange={(e) => {
-        console.log(e.currentTarget.value, value)
-        onChange(e.currentTarget.value)
-      }}>
-        {value !== undefined ? <option selected>
-          {list[value]}
-        </option> : <option selected disabled>
-            Select one option
-        </option>}
-        {Object.keys(list)
-          .filter((l) => l !== value)
-          .map(key => <option value={key} key={key}>{list[key]}</option>)
-        }
-      </select>
-    </NiceSelect>
-    {description && <span
-      style={{
-        color: "#383838",
-        fontSize: "smaller",
-        display: "block",
-        marginLeft: "2em",
-      }}
-    >
-      {description}
-    </span>}
-
-  </div>
-
+export function SelectList({
+  name,
+  value,
+  list,
+  canBeNull,
+  onChange,
+  label,
+  description,
+}: Props): JSX.Element {
+  return (
+    <div>
+      <label
+        htmlFor={`text-${name}`}
+        style={{ marginLeft: "0.5em", fontWeight: "bold" }}
+      >
+        {" "}
+        {label}
+      </label>
+      <NiceSelect>
+        <select
+          name={name}
+          onChange={(e) => {
+            console.log(e.currentTarget.value, value);
+            onChange(e.currentTarget.value);
+          }}
+        >
+          {value !== undefined ? (
+            <option selected>{list[value]}</option>
+          ) : (
+            <option selected disabled>
+              Select one option
+            </option>
+          )}
+          {Object.keys(list)
+            .filter((l) => l !== value)
+            .map((key) => (
+              <option value={key} key={key}>
+                {list[key]}
+              </option>
+            ))}
+        </select>
+      </NiceSelect>
+      {description && (
+        <span
+          style={{
+            color: "#383838",
+            fontSize: "smaller",
+            display: "block",
+            marginLeft: "2em",
+          }}
+        >
+          {description}
+        </span>
+      )}
+    </div>
+  );
 }
diff --git 
a/packages/taler-wallet-webextension/src/components/TransactionItem.tsx 
b/packages/taler-wallet-webextension/src/components/TransactionItem.tsx
index 991e97c9..1917d562 100644
--- a/packages/taler-wallet-webextension/src/components/TransactionItem.tsx
+++ b/packages/taler-wallet-webextension/src/components/TransactionItem.tsx
@@ -14,18 +14,33 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { AmountString, Timestamp, Transaction, TransactionType } from 
'@gnu-taler/taler-util';
-import { format, formatDistance } from 'date-fns';
-import { h } from 'preact';
-import imageBank from '../../static/img/ri-bank-line.svg';
-import imageHandHeart from '../../static/img/ri-hand-heart-line.svg';
-import imageRefresh from '../../static/img/ri-refresh-line.svg';
-import imageRefund from '../../static/img/ri-refund-2-line.svg';
-import imageShoppingCart from '../../static/img/ri-shopping-cart-line.svg';
+import {
+  AmountString,
+  Timestamp,
+  Transaction,
+  TransactionType,
+} from "@gnu-taler/taler-util";
+import { format, formatDistance } from "date-fns";
+import { h } from "preact";
+import imageBank from "../../static/img/ri-bank-line.svg";
+import imageHandHeart from "../../static/img/ri-hand-heart-line.svg";
+import imageRefresh from "../../static/img/ri-refresh-line.svg";
+import imageRefund from "../../static/img/ri-refund-2-line.svg";
+import imageShoppingCart from "../../static/img/ri-shopping-cart-line.svg";
 import { Pages } from "../NavigationBar";
-import { Column, ExtraLargeText, HistoryRow, SmallLightText, LargeText, 
LightText } from './styled/index';
+import {
+  Column,
+  ExtraLargeText,
+  HistoryRow,
+  SmallLightText,
+  LargeText,
+  LightText,
+} from "./styled/index";
 
-export function TransactionItem(props: { tx: Transaction, multiCurrency: 
boolean }): JSX.Element {
+export function TransactionItem(props: {
+  tx: Transaction;
+  multiCurrency: boolean;
+}): JSX.Element {
   const tx = props.tx;
   switch (tx.type) {
     case TransactionType.Withdrawal:
@@ -112,20 +127,26 @@ export function TransactionItem(props: { tx: Transaction, 
multiCurrency: boolean
 
 function TransactionLayout(props: TransactionLayoutProps): JSX.Element {
   const date = new Date(props.timestamp.t_ms);
-  const dateStr = format(date, 'dd MMM, hh:mm')
+  const dateStr = format(date, "dd MMM, hh:mm");
 
   return (
-    <HistoryRow href={Pages.transaction.replace(':tid', props.id)}>
+    <HistoryRow href={Pages.transaction.replace(":tid", props.id)}>
       <img src={props.iconPath} />
       <Column>
         <LargeText>
           <div>{props.title}</div>
-          {props.subtitle && <div style={{color:'gray', fontSize:'medium', 
marginTop: 5}}>{props.subtitle}</div>}
+          {props.subtitle && (
+            <div style={{ color: "gray", fontSize: "medium", marginTop: 5 }}>
+              {props.subtitle}
+            </div>
+          )}
         </LargeText>
-        {props.pending &&
-          <LightText style={{ marginTop: 5, marginBottom: 5 }}>Waiting for 
confirmation</LightText>
-        }
-        <SmallLightText style={{marginTop:5 }}>{dateStr}</SmallLightText>
+        {props.pending && (
+          <LightText style={{ marginTop: 5, marginBottom: 5 }}>
+            Waiting for confirmation
+          </LightText>
+        )}
+        <SmallLightText style={{ marginTop: 5 }}>{dateStr}</SmallLightText>
       </Column>
       <TransactionAmount
         pending={props.pending}
@@ -170,14 +191,18 @@ function TransactionAmount(props: 
TransactionAmountProps): JSX.Element {
       sign = "";
   }
   return (
-    <Column style={{
-      textAlign: 'center',
-      color:
-        props.pending ? "gray" :
-          (sign === '+' ? 'darkgreen' :
-            (sign === '-' ? 'darkred' :
-              undefined))
-    }}>
+    <Column
+      style={{
+        textAlign: "center",
+        color: props.pending
+          ? "gray"
+          : sign === "+"
+          ? "darkgreen"
+          : sign === "-"
+          ? "darkred"
+          : undefined,
+      }}
+    >
       <ExtraLargeText>
         {sign}
         {amount}
@@ -187,4 +212,3 @@ function TransactionAmount(props: TransactionAmountProps): 
JSX.Element {
     </Column>
   );
 }
-
diff --git a/packages/taler-wallet-webextension/src/components/styled/index.tsx 
b/packages/taler-wallet-webextension/src/components/styled/index.tsx
index 65c1f49e..8b36dbd3 100644
--- a/packages/taler-wallet-webextension/src/components/styled/index.tsx
+++ b/packages/taler-wallet-webextension/src/components/styled/index.tsx
@@ -14,18 +14,17 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-
 // need to import linaria types, otherwise compiler will complain
-import type * as Linaria from '@linaria/core';
+import type * as Linaria from "@linaria/core";
 
-import { styled } from '@linaria/react';
+import { styled } from "@linaria/react";
 
 export const PaymentStatus = styled.div<{ color: string }>`
   padding: 5px;
   border-radius: 5px;
   color: white;
-  background-color: ${p => p.color};
-`
+  background-color: ${(p) => p.color};
+`;
 
 export const WalletAction = styled.div`
   display: flex;
@@ -36,9 +35,9 @@ export const WalletAction = styled.div`
 
   margin: auto;
   height: 100%;
-  
+
   & h1:first-child {
-    margin-top: 0; 
+    margin-top: 0;
   }
   section {
     margin-bottom: 2em;
@@ -47,7 +46,7 @@ export const WalletAction = styled.div`
       margin-left: 8px;
     }
   }
-`
+`;
 export const WalletActionOld = styled.section`
   border: solid 5px black;
   border-radius: 10px;
@@ -59,17 +58,17 @@ export const WalletActionOld = styled.section`
 
   margin: auto;
   height: 100%;
-  
+
   & h1:first-child {
-    margin-top: 0; 
+    margin-top: 0;
   }
-`
+`;
 
 export const DateSeparator = styled.div`
   color: gray;
-  margin: .2em;
+  margin: 0.2em;
   margin-top: 1em;
-`
+`;
 export const WalletBox = styled.div<{ noPadding?: boolean }>`
   display: flex;
   flex-direction: column;
@@ -79,10 +78,10 @@ export const WalletBox = styled.div<{ noPadding?: boolean 
}>`
     width: 400px;
   }
   & > section {
-    padding-left: ${({ noPadding }) => noPadding ? '0px' : '8px'};
-    padding-right: ${({ noPadding }) => noPadding ? '0px' : '8px'};
+    padding-left: ${({ noPadding }) => (noPadding ? "0px" : "8px")};
+    padding-right: ${({ noPadding }) => (noPadding ? "0px" : "8px")};
     // this margin will send the section up when used with a header
-    margin-bottom: auto; 
+    margin-bottom: auto;
     overflow: auto;
 
     table td {
@@ -128,13 +127,13 @@ export const WalletBox = styled.div<{ noPadding?: boolean 
}>`
       margin-left: 8px;
     }
   }
-`
+`;
 export const Middle = styled.div`
-    justify-content: space-around;
-    display: flex;
-    flex-direction: column;
-    height: 100%;
-`
+  justify-content: space-around;
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+`;
 
 export const PopupBox = styled.div<{ noPadding?: boolean }>`
   height: 290px;
@@ -144,9 +143,9 @@ export const PopupBox = styled.div<{ noPadding?: boolean }>`
   justify-content: space-between;
 
   & > section {
-    padding: ${({ noPadding }) => noPadding ? '0px' : '8px'};
+    padding: ${({ noPadding }) => (noPadding ? "0px" : "8px")};
     // this margin will send the section up when used with a header
-    margin-bottom: auto; 
+    margin-bottom: auto;
     overflow-y: auto;
 
     table td {
@@ -201,8 +200,7 @@ export const PopupBox = styled.div<{ noPadding?: boolean }>`
       margin-left: 8px;
     }
   }
-
-`
+`;
 
 export const Button = styled.button<{ upperCased?: boolean }>`
   display: inline-block;
@@ -214,7 +212,7 @@ export const Button = styled.button<{ upperCased?: boolean 
}>`
   cursor: pointer;
   user-select: none;
   box-sizing: border-box;
-  text-transform: ${({ upperCased }) => upperCased ? 'uppercase' : 'none'};
+  text-transform: ${({ upperCased }) => (upperCased ? "uppercase" : "none")};
 
   font-family: inherit;
   font-size: 100%;
@@ -223,7 +221,7 @@ export const Button = styled.button<{ upperCased?: boolean 
}>`
   color: rgba(0, 0, 0, 0.8); /* rgba supported */
   border: 1px solid #999; /*IE 6/7/8*/
   border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/
-  background-color: '#e6e6e6';
+  background-color: "#e6e6e6";
   text-decoration: none;
   border-radius: 2px;
 
@@ -263,7 +261,7 @@ export const Link = styled.a<{ upperCased?: boolean }>`
   cursor: pointer;
   user-select: none;
   box-sizing: border-box;
-  text-transform: ${({ upperCased }) => upperCased ? 'uppercase' : 'none'};
+  text-transform: ${({ upperCased }) => (upperCased ? "uppercase" : "none")};
 
   font-family: inherit;
   font-size: 100%;
@@ -304,9 +302,9 @@ export const FontIcon = styled.div`
   text-align: center;
   font-weight: bold;
   /* vertical-align: text-top; */
-`
+`;
 export const ButtonBox = styled(Button)`
-  padding: .5em;
+  padding: 0.5em;
   width: fit-content;
   height: 2em;
 
@@ -322,89 +320,87 @@ export const ButtonBox = styled(Button)`
   border-radius: 4px;
   border-color: black;
   color: black;
-`
-
+`;
 
 const ButtonVariant = styled(Button)`
   color: white;
   border-radius: 4px;
   text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-`
+`;
 
 export const ButtonPrimary = styled(ButtonVariant)`
   background-color: rgb(66, 184, 221);
-`
+`;
 export const ButtonBoxPrimary = styled(ButtonBox)`
   color: rgb(66, 184, 221);
   border-color: rgb(66, 184, 221);
-`
+`;
 
 export const ButtonSuccess = styled(ButtonVariant)`
   background-color: #388e3c;
-`
+`;
 export const LinkSuccess = styled(Link)`
   color: #388e3c;
-`
+`;
 export const ButtonBoxSuccess = styled(ButtonBox)`
   color: #388e3c;
   border-color: #388e3c;
-`
+`;
 
 export const ButtonWarning = styled(ButtonVariant)`
   background-color: rgb(223, 117, 20);
-`
+`;
 export const LinkWarning = styled(Link)`
   color: rgb(223, 117, 20);
-`
+`;
 export const ButtonBoxWarning = styled(ButtonBox)`
   color: rgb(223, 117, 20);
   border-color: rgb(223, 117, 20);
-`
+`;
 
 export const ButtonDestructive = styled(ButtonVariant)`
   background-color: rgb(202, 60, 60);
-`
+`;
 export const ButtonBoxDestructive = styled(ButtonBox)`
   color: rgb(202, 60, 60);
   border-color: rgb(202, 60, 60);
-`
-
+`;
 
 export const BoldLight = styled.div`
-color: gray;
-font-weight: bold;
-`
+  color: gray;
+  font-weight: bold;
+`;
 export const Centered = styled.div`
   text-align: center;
   & > :not(:first-child) {
     margin-top: 15px;
   }
-`
+`;
 export const Row = styled.div`
   display: flex;
   margin: 0.5em 0;
   justify-content: space-between;
   padding: 0.5em;
-`
+`;
 
 export const Row2 = styled.div`
   display: flex;
   /* margin: 0.5em 0; */
   justify-content: space-between;
   padding: 0.5em;
-`
+`;
 
 export const Column = styled.div`
   display: flex;
   flex-direction: column;
   margin: 0em 1em;
   justify-content: space-between;
-`
+`;
 
 export const RowBorderGray = styled(Row)`
   border: 1px solid gray;
   /* border-radius: 0.5em; */
-`
+`;
 
 export const RowLightBorderGray = styled(Row2)`
   border: 1px solid lightgray;
@@ -414,7 +410,7 @@ export const RowLightBorderGray = styled(Row2)`
     border: 1px solid lightgray;
     background-color: red;
   }
-`
+`;
 
 export const HistoryRow = styled.a`
   text-decoration: none;
@@ -423,7 +419,7 @@ export const HistoryRow = styled.a`
   display: flex;
   justify-content: space-between;
   padding: 0.5em;
-  
+
   border: 1px solid lightgray;
   border-top: 0px;
 
@@ -439,7 +435,7 @@ export const HistoryRow = styled.a`
     margin-left: auto;
     align-self: center;
   }
-`
+`;
 
 export const ListOfProducts = styled.div`
   & > div > a > img {
@@ -453,62 +449,62 @@ export const ListOfProducts = styled.div`
     margin-right: auto;
     margin-left: 1em;
   }
-`
+`;
 
 export const LightText = styled.div`
   color: gray;
-`
+`;
 
 export const WarningText = styled.div`
   color: rgb(223, 117, 20);
-`
+`;
 
 export const SmallText = styled.div`
-  font-size: small; 
-`
+  font-size: small;
+`;
 export const LargeText = styled.div`
-  font-size: large; 
-`
+  font-size: large;
+`;
 
 export const ExtraLargeText = styled.div`
-  font-size: x-large; 
-`
+  font-size: x-large;
+`;
 
 export const SmallLightText = styled(SmallText)`
   color: gray;
-`
+`;
 
 export const CenteredText = styled.div`
   white-space: nowrap;
   text-align: center;
-`
+`;
 
 export const CenteredBoldText = styled(CenteredText)`
   white-space: nowrap;
   text-align: center;
   font-weight: bold;
   color: ${((props: any): any => String(props.color) as any) as any};
-`
+`;
 
 export const Input = styled.div<{ invalid?: boolean }>`
   & label {
     display: block;
     padding: 5px;
-    color: ${({ invalid }) => !invalid ? 'inherit' : 'red'}
+    color: ${({ invalid }) => (!invalid ? "inherit" : "red")};
   }
   & input {
     display: block;
     padding: 5px;
     width: calc(100% - 4px - 10px);
-    border-color: ${({ invalid }) => !invalid ? 'inherit' : 'red'}
+    border-color: ${({ invalid }) => (!invalid ? "inherit" : "red")};
   }
-`
+`;
 
 export const InputWithLabel = styled.div<{ invalid?: boolean }>`
   & label {
     display: block;
     padding: 5px;
-    color: ${({ invalid }) => !invalid ? 'inherit' : 'red'}
+    color: ${({ invalid }) => (!invalid ? "inherit" : "red")};
   }
   & > div {
     position: relative;
@@ -516,20 +512,20 @@ export const InputWithLabel = styled.div<{ invalid?: 
boolean }>`
     top: 0px;
     bottom: 0px;
 
-    &  > div {
+    & > div {
       position: absolute;
       background-color: lightgray;
       padding: 5px;
       margin: 2px;
     }
 
-    &  > input {
+    & > input {
       flex: 1;
-      padding: 5px; 
-      border-color: ${({ invalid }) => !invalid ? 'inherit' : 'red'}
+      padding: 5px;
+      border-color: ${({ invalid }) => (!invalid ? "inherit" : "red")};
     }
   }
-`
+`;
 
 export const ErrorBox = styled.div`
   border: 2px solid #f5c6cb;
@@ -555,22 +551,22 @@ export const ErrorBox = styled.div`
       width: 28px;
     }
   }
-`
+`;
 
 export const SuccessBox = styled(ErrorBox)`
   color: #0f5132;
   background-color: #d1e7dd;
   border-color: #badbcc;
-`
+`;
 
 export const WarningBox = styled(ErrorBox)`
   color: #664d03;
   background-color: #fff3cd;
   border-color: #ffecb5;
-`
+`;
 
 export const PopupNavigation = styled.div<{ devMode?: boolean }>`
-  background-color:#0042b2;
+  background-color: #0042b2;
   height: 35px;
   justify-content: space-around;
   display: flex;
@@ -582,7 +578,7 @@ export const PopupNavigation = styled.div<{ devMode?: 
boolean }>`
   & > div > a {
     color: #f8faf7;
     display: inline-block;
-    width: calc(400px / ${({ devMode }) => !devMode ? 4 : 5});
+    width: calc(400px / ${({ devMode }) => (!devMode ? 4 : 5)});
     text-align: center;
     text-decoration: none;
     vertical-align: middle;
@@ -597,7 +593,6 @@ export const PopupNavigation = styled.div<{ devMode?: 
boolean }>`
 `;
 
 export const NiceSelect = styled.div`
-
   & > select {
     -webkit-appearance: none;
     -moz-appearance: none;
@@ -617,19 +612,19 @@ export const NiceSelect = styled.div`
   display: flex;
   /* width: 10em; */
   overflow: hidden;
-  border-radius: .25em;
+  border-radius: 0.25em;
 
   &::after {
-    content: '\u25BC';
+    content: "\u25BC";
     position: absolute;
     top: 0;
     right: 0;
     padding: 0.5em 1em;
     cursor: pointer;
     pointer-events: none;
-    -webkit-transition: .25s all ease;
-    -o-transition: .25s all ease;
-    transition: .25s all ease;
+    -webkit-transition: 0.25s all ease;
+    -o-transition: 0.25s all ease;
+    transition: 0.25s all ease;
   }
 
   &:hover::after {
@@ -639,7 +634,7 @@ export const NiceSelect = styled.div`
   &::-ms-expand {
     display: none;
   }
-`
+`;
 
 export const Outlined = styled.div`
   border: 2px solid #388e3c;
@@ -647,13 +642,12 @@ export const Outlined = styled.div`
   width: fit-content;
   border-radius: 2px;
   color: #388e3c;
-`
+`;
 
 /* { width: "1.5em", height: "1.5em", verticalAlign: "middle" } */
 export const CheckboxSuccess = styled.input`
   vertical-align: center;
-
-`
+`;
 
 export const TermsSection = styled.a`
   border: 1px solid black;
@@ -664,13 +658,13 @@ export const TermsSection = styled.a`
   text-decoration: none;
   color: inherit;
   flex-direction: column;
-  
+
   display: flex;
   &[data-open="true"] {
-    display: flex; 
+    display: flex;
   }
   &[data-open="false"] > *:not(:first-child) {
-    display: none; 
+    display: none;
   }
 
   header {
@@ -681,11 +675,11 @@ export const TermsSection = styled.a`
     height: auto;
   }
 
-  &[data-open="true"] header:after  {
-    content: '\\2227';
+  &[data-open="true"] header:after {
+    content: "\\2227";
   }
-  &[data-open="false"] header:after  {
-    content: '\\2228';
+  &[data-open="false"] header:after {
+    content: "\\2228";
   }
 `;
 
@@ -712,13 +706,13 @@ export const TermsOfService = styled.div`
     padding: 1em;
     margin-top: 2px;
     margin-bottom: 2px;
-    
+
     display: flex;
     &[data-open="true"] {
-      display: flex; 
+      display: flex;
     }
     &[data-open="false"] > *:not(:first-child) {
-      display: none; 
+      display: none;
     }
 
     header {
@@ -729,22 +723,20 @@ export const TermsOfService = styled.div`
       height: auto;
     }
 
-    &[data-open="true"] > header:after  {
-      content: '\\2227';
+    &[data-open="true"] > header:after {
+      content: "\\2227";
     }
-    &[data-open="false"] > header:after  {
-      content: '\\2228';
+    &[data-open="false"] > header:after {
+      content: "\\2228";
     }
   }
-
-`
+`;
 export const StyledCheckboxLabel = styled.div`
   color: green;
   text-transform: uppercase;
   /* font-weight: bold; */
   text-align: center;
   span {
-
     input {
       display: none;
       opacity: 0;
@@ -758,7 +750,7 @@ export const StyledCheckboxLabel = styled.div`
       margin-right: 1em;
       border-radius: 2px;
       border: 2px solid currentColor;
-  
+
       svg {
         transition: transform 0.1s ease-in 25ms;
         transform: scale(0);
@@ -776,12 +768,11 @@ export const StyledCheckboxLabel = styled.div`
   }
   input:disabled + div {
     color: #959495;
-  };
+  }
   input:disabled + div + label {
     color: #959495;
-  };
+  }
   input:focus + div + label {
     box-shadow: 0 0 0 0.05em #fff, 0 0 0.15em 0.1em currentColor;
   }
-
-`
\ No newline at end of file
+`;
diff --git a/packages/taler-wallet-webextension/src/context/devContext.ts 
b/packages/taler-wallet-webextension/src/context/devContext.ts
index ea2ba4ce..0344df05 100644
--- a/packages/taler-wallet-webextension/src/context/devContext.ts
+++ b/packages/taler-wallet-webextension/src/context/devContext.ts
@@ -15,13 +15,13 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createContext, h, VNode } from 'preact'
-import { useContext, useState } from 'preact/hooks'
-import { useLocalStorage } from '../hooks/useLocalStorage';
+import { createContext, h, VNode } from "preact";
+import { useContext, useState } from "preact/hooks";
+import { useLocalStorage } from "../hooks/useLocalStorage";
 
 interface Type {
   devMode: boolean;
@@ -29,14 +29,14 @@ interface Type {
 }
 const Context = createContext<Type>({
   devMode: false,
-  toggleDevMode: () => null
-})
+  toggleDevMode: () => null,
+});
 
 export const useDevContext = (): Type => useContext(Context);
 
 export const DevContextProvider = ({ children }: { children: any }): VNode => {
-  const [value, setter] = useLocalStorage('devMode')
-  const devMode = value === "true"
-  const toggleDevMode = () => setter(v => !v ? "true" : undefined)
+  const [value, setter] = useLocalStorage("devMode");
+  const devMode = value === "true";
+  const toggleDevMode = () => setter((v) => (!v ? "true" : undefined));
   return h(Context.Provider, { value: { devMode, toggleDevMode }, children });
-}
+};
diff --git a/packages/taler-wallet-webextension/src/context/translation.ts 
b/packages/taler-wallet-webextension/src/context/translation.ts
index 5f57958d..105da9dc 100644
--- a/packages/taler-wallet-webextension/src/context/translation.ts
+++ b/packages/taler-wallet-webextension/src/context/translation.ts
@@ -15,54 +15,58 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createContext, h, VNode } from 'preact'
-import { useContext, useEffect } from 'preact/hooks'
-import { useLang } from '../hooks/useLang'
+import { createContext, h, VNode } from "preact";
+import { useContext, useEffect } from "preact/hooks";
+import { useLang } from "../hooks/useLang";
 //@ts-ignore: type declaration
 import * as jedLib from "jed";
 import { strings } from "../i18n/strings";
-import { setupI18n } from '@gnu-taler/taler-util';
+import { setupI18n } from "@gnu-taler/taler-util";
 
 interface Type {
   lang: string;
   changeLanguage: (l: string) => void;
 }
 const initial = {
-  lang: 'en',
+  lang: "en",
   changeLanguage: () => {
     // do not change anything
-  }
-}
-const Context = createContext<Type>(initial)
+  },
+};
+const Context = createContext<Type>(initial);
 
 interface Props {
-  initial?: string,
-  children: any,
-  forceLang?: string
+  initial?: string;
+  children: any;
+  forceLang?: string;
 }
 
-//we use forceLang when we don't want to use the saved state, but sone forced 
-//runtime lang predefined lang 
-export const TranslationProvider = ({ initial, children, forceLang }: Props): 
VNode => {
-  const [lang, changeLanguage] = useLang(initial)
+//we use forceLang when we don't want to use the saved state, but sone forced
+//runtime lang predefined lang
+export const TranslationProvider = ({
+  initial,
+  children,
+  forceLang,
+}: Props): VNode => {
+  const [lang, changeLanguage] = useLang(initial);
   useEffect(() => {
     if (forceLang) {
-      changeLanguage(forceLang)
+      changeLanguage(forceLang);
     }
-  })
-  useEffect(()=> {
-    setupI18n(lang, strings)
-  },[lang])
+  });
+  useEffect(() => {
+    setupI18n(lang, strings);
+  }, [lang]);
   if (forceLang) {
-    setupI18n(forceLang, strings)
+    setupI18n(forceLang, strings);
   } else {
-    setupI18n(lang, strings)    
+    setupI18n(lang, strings);
   }
   return h(Context.Provider, { value: { lang, changeLanguage }, children });
-}
+};
 
 export const useTranslationContext = (): Type => useContext(Context);
diff --git a/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx 
b/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx
index 622e7950..c2d360d3 100644
--- a/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx
@@ -15,150 +15,156 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { ContractTerms, PreparePayResultType } from '@gnu-taler/taler-util';
-import { createExample } from '../test-utils';
-import { PaymentRequestView as TestedComponent } from './Pay';
+import { ContractTerms, PreparePayResultType } from "@gnu-taler/taler-util";
+import { createExample } from "../test-utils";
+import { PaymentRequestView as TestedComponent } from "./Pay";
 
 export default {
-  title: 'cta/pay',
+  title: "cta/pay",
   component: TestedComponent,
-  argTypes: {
-  },
+  argTypes: {},
 };
 
 export const NoBalance = createExample(TestedComponent, {
   payStatus: {
     status: PreparePayResultType.InsufficientBalance,
-    noncePriv: '',
+    noncePriv: "",
     proposalId: "proposal1234",
-    contractTerms: {
+    contractTerms: ({
       merchant: {
-        name: 'someone'
+        name: "someone",
       },
-      summary: 'some beers',
-      amount: 'USD:10',
-    } as Partial<ContractTerms> as any,
-    amountRaw: 'USD:10',
-  }
+      summary: "some beers",
+      amount: "USD:10",
+    } as Partial<ContractTerms>) as any,
+    amountRaw: "USD:10",
+  },
 });
 
 export const NoEnoughBalance = createExample(TestedComponent, {
   payStatus: {
     status: PreparePayResultType.InsufficientBalance,
-    noncePriv: '',
+    noncePriv: "",
     proposalId: "proposal1234",
-    contractTerms: {
+    contractTerms: ({
       merchant: {
-        name: 'someone'
+        name: "someone",
       },
-      summary: 'some beers',
-      amount: 'USD:10',
-    } as Partial<ContractTerms> as any,
-    amountRaw: 'USD:10',
+      summary: "some beers",
+      amount: "USD:10",
+    } as Partial<ContractTerms>) as any,
+    amountRaw: "USD:10",
   },
   balance: {
-    currency: 'USD',
+    currency: "USD",
     fraction: 40000000,
-    value: 9
-  }
+    value: 9,
+  },
 });
 
 export const PaymentPossible = createExample(TestedComponent, {
-  uri: 
'taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0',
+  uri:
+    
"taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0",
   payStatus: {
     status: PreparePayResultType.PaymentPossible,
-    amountEffective: 'USD:10',
-    amountRaw: 'USD:10',
-    noncePriv: '',
-    contractTerms: {
-      nonce: '123213123',
+    amountEffective: "USD:10",
+    amountRaw: "USD:10",
+    noncePriv: "",
+    contractTerms: ({
+      nonce: "123213123",
       merchant: {
-        name: 'someone'
+        name: "someone",
       },
-      amount: 'USD:10',
-      summary: 'some beers',
-    } as Partial<ContractTerms> as any,
-    contractTermsHash: '123456',
-    proposalId: 'proposal1234'
-  }
+      amount: "USD:10",
+      summary: "some beers",
+    } as Partial<ContractTerms>) as any,
+    contractTermsHash: "123456",
+    proposalId: "proposal1234",
+  },
 });
 
 export const PaymentPossibleWithFee = createExample(TestedComponent, {
-  uri: 
'taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0',
+  uri:
+    
"taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0",
   payStatus: {
     status: PreparePayResultType.PaymentPossible,
-    amountEffective: 'USD:10.20',
-    amountRaw: 'USD:10',
-    noncePriv: '',
-    contractTerms: {
-      nonce: '123213123',
+    amountEffective: "USD:10.20",
+    amountRaw: "USD:10",
+    noncePriv: "",
+    contractTerms: ({
+      nonce: "123213123",
       merchant: {
-        name: 'someone'
+        name: "someone",
       },
-      amount: 'USD:10',
-      summary: 'some beers',
-    } as Partial<ContractTerms> as any,
-    contractTermsHash: '123456',
-    proposalId: 'proposal1234'
-  }
+      amount: "USD:10",
+      summary: "some beers",
+    } as Partial<ContractTerms>) as any,
+    contractTermsHash: "123456",
+    proposalId: "proposal1234",
+  },
 });
 
 export const AlreadyConfirmedWithFullfilment = createExample(TestedComponent, {
   payStatus: {
     status: PreparePayResultType.AlreadyConfirmed,
-    amountEffective: 'USD:10',
-    amountRaw: 'USD:10',
-    contractTerms: {
+    amountEffective: "USD:10",
+    amountRaw: "USD:10",
+    contractTerms: ({
       merchant: {
-        name: 'someone'
+        name: "someone",
       },
-      fulfillment_message: 'congratulations! you are looking at the 
fulfillment message! ',
-      summary: 'some beers',
-      amount: 'USD:10',
-    } as Partial<ContractTerms> as any,
-    contractTermsHash: '123456',
-    proposalId: 'proposal1234',
+      fulfillment_message:
+        "congratulations! you are looking at the fulfillment message! ",
+      summary: "some beers",
+      amount: "USD:10",
+    } as Partial<ContractTerms>) as any,
+    contractTermsHash: "123456",
+    proposalId: "proposal1234",
     paid: false,
-  }
+  },
 });
 
-export const AlreadyConfirmedWithoutFullfilment = 
createExample(TestedComponent, {
-  payStatus: {
-    status: PreparePayResultType.AlreadyConfirmed,
-    amountEffective: 'USD:10',
-    amountRaw: 'USD:10',
-    contractTerms: {
-      merchant: {
-        name: 'someone'
-      },
-      summary: 'some beers',
-      amount: 'USD:10',
-    } as Partial<ContractTerms> as any,
-    contractTermsHash: '123456',
-    proposalId: 'proposal1234',
-    paid: false,
-  }
-});
+export const AlreadyConfirmedWithoutFullfilment = createExample(
+  TestedComponent,
+  {
+    payStatus: {
+      status: PreparePayResultType.AlreadyConfirmed,
+      amountEffective: "USD:10",
+      amountRaw: "USD:10",
+      contractTerms: ({
+        merchant: {
+          name: "someone",
+        },
+        summary: "some beers",
+        amount: "USD:10",
+      } as Partial<ContractTerms>) as any,
+      contractTermsHash: "123456",
+      proposalId: "proposal1234",
+      paid: false,
+    },
+  },
+);
 
 export const AlreadyPaid = createExample(TestedComponent, {
   payStatus: {
     status: PreparePayResultType.AlreadyConfirmed,
-    amountEffective: 'USD:10',
-    amountRaw: 'USD:10',
-    contractTerms: {
+    amountEffective: "USD:10",
+    amountRaw: "USD:10",
+    contractTerms: ({
       merchant: {
-        name: 'someone'
+        name: "someone",
       },
-      fulfillment_message: 'congratulations! you are looking at the 
fulfillment message! ',
-      summary: 'some beers',
-      amount: 'USD:10',
-    } as Partial<ContractTerms> as any,
-    contractTermsHash: '123456',
-    proposalId: 'proposal1234',
+      fulfillment_message:
+        "congratulations! you are looking at the fulfillment message! ",
+      summary: "some beers",
+      amount: "USD:10",
+    } as Partial<ContractTerms>) as any,
+    contractTermsHash: "123456",
+    proposalId: "proposal1234",
     paid: true,
-  }
+  },
 });
diff --git a/packages/taler-wallet-webextension/src/cta/Pay.tsx 
b/packages/taler-wallet-webextension/src/cta/Pay.tsx
index 675b14ff..1023013d 100644
--- a/packages/taler-wallet-webextension/src/cta/Pay.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Pay.tsx
@@ -24,18 +24,36 @@
  */
 // import * as i18n from "../i18n";
 
-import { AmountJson, AmountLike, Amounts, ConfirmPayResult, 
ConfirmPayResultDone, ConfirmPayResultType, ContractTerms, getJsonI18n, i18n, 
PreparePayResult, PreparePayResultType } from "@gnu-taler/taler-util";
-import { Fragment, JSX, VNode } from "preact";
+import {
+  AmountJson,
+  AmountLike,
+  Amounts,
+  ConfirmPayResult,
+  ConfirmPayResultDone,
+  ConfirmPayResultType,
+  ContractTerms,
+  i18n,
+  PreparePayResult,
+  PreparePayResultType,
+} from "@gnu-taler/taler-util";
+import { h, Fragment, JSX, VNode } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import { LogoHeader } from "../components/LogoHeader";
 import { Part } from "../components/Part";
 import { QR } from "../components/QR";
-import { ButtonSuccess, ErrorBox, LinkSuccess, SuccessBox, WalletAction, 
WarningBox } from "../components/styled";
+import {
+  ButtonSuccess,
+  ErrorBox,
+  LinkSuccess,
+  SuccessBox,
+  WalletAction,
+  WarningBox,
+} from "../components/styled";
 import { useBalances } from "../hooks/useBalances";
 import * as wxApi from "../wxApi";
 
 interface Props {
-  talerPayUri?: string
+  talerPayUri?: string;
 }
 
 // export function AlreadyPaid({ payStatus }: { payStatus: PreparePayResult }) 
{
@@ -64,7 +82,9 @@ interface Props {
 //   </section>
 // }
 
-const doPayment = async (payStatus: PreparePayResult): 
Promise<ConfirmPayResultDone> => {
+const doPayment = async (
+  payStatus: PreparePayResult,
+): Promise<ConfirmPayResultDone> => {
   if (payStatus.status !== "payment-possible") {
     throw Error(`invalid state: ${payStatus.status}`);
   }
@@ -80,18 +100,29 @@ const doPayment = async (payStatus: PreparePayResult): 
Promise<ConfirmPayResultD
   return res;
 };
 
-
-
 export function PayPage({ talerPayUri }: Props): JSX.Element {
-  const [payStatus, setPayStatus] = useState<PreparePayResult | 
undefined>(undefined);
-  const [payResult, setPayResult] = useState<ConfirmPayResult | 
undefined>(undefined);
+  const [payStatus, setPayStatus] = useState<PreparePayResult | undefined>(
+    undefined,
+  );
+  const [payResult, setPayResult] = useState<ConfirmPayResult | undefined>(
+    undefined,
+  );
   const [payErrMsg, setPayErrMsg] = useState<string | undefined>(undefined);
 
-  const balance = useBalances()
-  const balanceWithoutError = balance?.hasError ? [] : 
(balance?.response.balances || [])
+  const balance = useBalances();
+  const balanceWithoutError = balance?.hasError
+    ? []
+    : balance?.response.balances || [];
 
-  const foundBalance = balanceWithoutError.find(b => payStatus && 
Amounts.parseOrThrow(b.available).currency === 
Amounts.parseOrThrow(payStatus?.amountRaw).currency)
-  const foundAmount = foundBalance ? 
Amounts.parseOrThrow(foundBalance.available) : undefined
+  const foundBalance = balanceWithoutError.find(
+    (b) =>
+      payStatus &&
+      Amounts.parseOrThrow(b.available).currency ===
+        Amounts.parseOrThrow(payStatus?.amountRaw).currency,
+  );
+  const foundAmount = foundBalance
+    ? Amounts.parseOrThrow(foundBalance.available)
+    : undefined;
 
   useEffect(() => {
     if (!talerPayUri) return;
@@ -101,7 +132,7 @@ export function PayPage({ talerPayUri }: Props): 
JSX.Element {
         setPayStatus(p);
       } catch (e) {
         if (e instanceof Error) {
-          setPayErrMsg(e.message)
+          setPayErrMsg(e.message);
         }
       }
     };
@@ -109,30 +140,28 @@ export function PayPage({ talerPayUri }: Props): 
JSX.Element {
   }, [talerPayUri]);
 
   if (!talerPayUri) {
-    return <span>missing pay uri</span>
+    return <span>missing pay uri</span>;
   }
 
   if (!payStatus) {
     if (payErrMsg) {
-      return <WalletAction>
-        <LogoHeader />
-        <h2>
-          {i18n.str`Digital cash payment`}
-        </h2>
-        <section>
-          <p>Could not get the payment information for this order</p>
-          <ErrorBox>
-            {payErrMsg}
-          </ErrorBox>
-        </section>
-      </WalletAction>
+      return (
+        <WalletAction>
+          <LogoHeader />
+          <h2>{i18n.str`Digital cash payment`}</h2>
+          <section>
+            <p>Could not get the payment information for this order</p>
+            <ErrorBox>{payErrMsg}</ErrorBox>
+          </section>
+        </WalletAction>
+      );
     }
     return <span>Loading payment information ...</span>;
   }
 
   const onClick = async () => {
     try {
-      const res = await doPayment(payStatus)
+      const res = await doPayment(payStatus);
       setPayResult(res);
     } catch (e) {
       console.error(e);
@@ -140,13 +169,18 @@ export function PayPage({ talerPayUri }: Props): 
JSX.Element {
         setPayErrMsg(e.message);
       }
     }
+  };
 
-  }
-
-  return <PaymentRequestView uri={talerPayUri}
-    payStatus={payStatus} payResult={payResult}
-    onClick={onClick} payErrMsg={payErrMsg}
-    balance={foundAmount} />;
+  return (
+    <PaymentRequestView
+      uri={talerPayUri}
+      payStatus={payStatus}
+      payResult={payResult}
+      onClick={onClick}
+      payErrMsg={payErrMsg}
+      balance={foundAmount}
+    />
+  );
 }
 
 export interface PaymentRequestViewProps {
@@ -157,7 +191,14 @@ export interface PaymentRequestViewProps {
   uri: string;
   balance: AmountJson | undefined;
 }
-export function PaymentRequestView({ uri, payStatus, payResult, onClick, 
payErrMsg, balance }: PaymentRequestViewProps) {
+export function PaymentRequestView({
+  uri,
+  payStatus,
+  payResult,
+  onClick,
+  payErrMsg,
+  balance,
+}: PaymentRequestViewProps) {
   let totalFees: AmountJson = Amounts.getZero(payStatus.amountRaw);
   const contractTerms: ContractTerms = payStatus.contractTerms;
 
@@ -185,116 +226,174 @@ export function PaymentRequestView({ uri, payStatus, 
payResult, onClick, payErrM
   }
 
   function Alternative() {
-    const [showQR, setShowQR] = useState<boolean>(false)
-    const privateUri = payStatus.status !== 
PreparePayResultType.AlreadyConfirmed ? `${uri}&n=${payStatus.noncePriv}` : uri
-    return <section>
-      <LinkSuccess upperCased onClick={() => setShowQR(qr => !qr)}>
-        {!showQR ? i18n.str`Pay with a mobile phone` : i18n.str`Hide QR`}
-      </LinkSuccess>
-      {showQR && <div>
-        <QR text={privateUri} />
-        Scan the QR code or <a href={privateUri}>click here</a>
-      </div>}
-    </section>
+    const [showQR, setShowQR] = useState<boolean>(false);
+    const privateUri =
+      payStatus.status !== PreparePayResultType.AlreadyConfirmed
+        ? `${uri}&n=${payStatus.noncePriv}`
+        : uri;
+    return (
+      <section>
+        <LinkSuccess upperCased onClick={() => setShowQR((qr) => !qr)}>
+          {!showQR ? i18n.str`Pay with a mobile phone` : i18n.str`Hide QR`}
+        </LinkSuccess>
+        {showQR && (
+          <div>
+            <QR text={privateUri} />
+            Scan the QR code or <a href={privateUri}>click here</a>
+          </div>
+        )}
+      </section>
+    );
   }
 
   function ButtonsSection() {
     if (payResult) {
       if (payResult.type === ConfirmPayResultType.Pending) {
-        return <section>
-          <div>
-            <p>Processing...</p>
-          </div>
-        </section>
+        return (
+          <section>
+            <div>
+              <p>Processing...</p>
+            </div>
+          </section>
+        );
       }
-      return null
+      return null;
     }
     if (payErrMsg) {
-      return <section>
-        <div>
-          <p>Payment failed: {payErrMsg}</p>
-          <button class="pure-button button-success" onClick={onClick} >
-            {i18n.str`Retry`}
-          </button>
-        </div>
-      </section>
-    }
-    if (payStatus.status === PreparePayResultType.PaymentPossible) {
-      return <Fragment>
+      return (
         <section>
-          <ButtonSuccess upperCased onClick={onClick}>
-            {i18n.str`Pay`} {amountToString(payStatus.amountEffective)}
-          </ButtonSuccess>
+          <div>
+            <p>Payment failed: {payErrMsg}</p>
+            <button class="pure-button button-success" onClick={onClick}>
+              {i18n.str`Retry`}
+            </button>
+          </div>
         </section>
-        <Alternative />
-      </Fragment>
+      );
+    }
+    if (payStatus.status === PreparePayResultType.PaymentPossible) {
+      return (
+        <Fragment>
+          <section>
+            <ButtonSuccess upperCased onClick={onClick}>
+              {i18n.str`Pay`} {amountToString(payStatus.amountEffective)}
+            </ButtonSuccess>
+          </section>
+          <Alternative />
+        </Fragment>
+      );
     }
     if (payStatus.status === PreparePayResultType.InsufficientBalance) {
-      return <Fragment>
-        <section>
-          {balance ? <WarningBox>
-            Your balance of {amountToString(balance)} is not enough to pay for 
this purchase
-          </WarningBox> : <WarningBox>
-            Your balance is not enough to pay for this purchase.
-          </WarningBox>}
-        </section>
-        <section>
-          <ButtonSuccess upperCased>
-            {i18n.str`Withdraw digital cash`}
-          </ButtonSuccess>
-        </section>
-        <Alternative />
-      </Fragment>
+      return (
+        <Fragment>
+          <section>
+            {balance ? (
+              <WarningBox>
+                Your balance of {amountToString(balance)} is not enough to pay
+                for this purchase
+              </WarningBox>
+            ) : (
+              <WarningBox>
+                Your balance is not enough to pay for this purchase.
+              </WarningBox>
+            )}
+          </section>
+          <section>
+            <ButtonSuccess upperCased>
+              {i18n.str`Withdraw digital cash`}
+            </ButtonSuccess>
+          </section>
+          <Alternative />
+        </Fragment>
+      );
     }
     if (payStatus.status === PreparePayResultType.AlreadyConfirmed) {
-      return <Fragment>
-        <section>
-          {payStatus.paid && contractTerms.fulfillment_message && <Part 
title="Merchant message" text={contractTerms.fulfillment_message} 
kind='neutral' />}
-        </section>
-        {!payStatus.paid && <Alternative />}
-      </Fragment>
+      return (
+        <Fragment>
+          <section>
+            {payStatus.paid && contractTerms.fulfillment_message && (
+              <Part
+                title="Merchant message"
+                text={contractTerms.fulfillment_message}
+                kind="neutral"
+              />
+            )}
+          </section>
+          {!payStatus.paid && <Alternative />}
+        </Fragment>
+      );
     }
-    return <span />
+    return <span />;
   }
 
-  return <WalletAction>
-    <LogoHeader />
-
-    <h2>
-      {i18n.str`Digital cash payment`}
-    </h2>
-    {payStatus.status === PreparePayResultType.AlreadyConfirmed &&
-      (payStatus.paid ? <SuccessBox> Already paid </SuccessBox> : <WarningBox> 
Already claimed </WarningBox>)
-    }
-    {payResult && payResult.type === ConfirmPayResultType.Done && (
-      <SuccessBox>
-        <h3>Payment complete</h3>
-        <p>{!payResult.contractTerms.fulfillment_message ?
-          "You will now be sent back to the merchant you came from." :
-          payResult.contractTerms.fulfillment_message
-        }</p>
-      </SuccessBox>
-    )}
-    <section>
-      {payStatus.status !== PreparePayResultType.InsufficientBalance && 
Amounts.isNonZero(totalFees) &&
-        <Part big title="Total to pay" 
text={amountToString(payStatus.amountEffective)} kind='negative' />
-      }
-      <Part big title="Purchase amount" 
text={amountToString(payStatus.amountRaw)} kind='neutral' />
-      {Amounts.isNonZero(totalFees) && <Fragment>
-        <Part big title="Fee" text={amountToString(totalFees)} kind='negative' 
/>
-      </Fragment>
-      }
-      <Part title="Merchant" text={contractTerms.merchant.name} kind='neutral' 
/>
-      <Part title="Purchase" text={contractTerms.summary} kind='neutral' />
-      {contractTerms.order_id && <Part title="Receipt" 
text={`#${contractTerms.order_id}`} kind='neutral' />}
-    </section>
-    <ButtonsSection />
+  return (
+    <WalletAction>
+      <LogoHeader />
 
-  </WalletAction>
+      <h2>{i18n.str`Digital cash payment`}</h2>
+      {payStatus.status === PreparePayResultType.AlreadyConfirmed &&
+        (payStatus.paid ? (
+          <SuccessBox> Already paid </SuccessBox>
+        ) : (
+          <WarningBox> Already claimed </WarningBox>
+        ))}
+      {payResult && payResult.type === ConfirmPayResultType.Done && (
+        <SuccessBox>
+          <h3>Payment complete</h3>
+          <p>
+            {!payResult.contractTerms.fulfillment_message
+              ? "You will now be sent back to the merchant you came from."
+              : payResult.contractTerms.fulfillment_message}
+          </p>
+        </SuccessBox>
+      )}
+      <section>
+        {payStatus.status !== PreparePayResultType.InsufficientBalance &&
+          Amounts.isNonZero(totalFees) && (
+            <Part
+              big
+              title="Total to pay"
+              text={amountToString(payStatus.amountEffective)}
+              kind="negative"
+            />
+          )}
+        <Part
+          big
+          title="Purchase amount"
+          text={amountToString(payStatus.amountRaw)}
+          kind="neutral"
+        />
+        {Amounts.isNonZero(totalFees) && (
+          <Fragment>
+            <Part
+              big
+              title="Fee"
+              text={amountToString(totalFees)}
+              kind="negative"
+            />
+          </Fragment>
+        )}
+        <Part
+          title="Merchant"
+          text={contractTerms.merchant.name}
+          kind="neutral"
+        />
+        <Part title="Purchase" text={contractTerms.summary} kind="neutral" />
+        {contractTerms.order_id && (
+          <Part
+            title="Receipt"
+            text={`#${contractTerms.order_id}`}
+            kind="neutral"
+          />
+        )}
+      </section>
+      <ButtonsSection />
+    </WalletAction>
+  );
 }
 
 function amountToString(text: AmountLike) {
-  const aj = Amounts.jsonifyAmount(text)
-  const amount = Amounts.stringifyValue(aj, 2)
-  return `${amount} ${aj.currency}`
+  const aj = Amounts.jsonifyAmount(text);
+  const amount = Amounts.stringifyValue(aj, 2);
+  return `${amount} ${aj.currency}`;
 }
diff --git a/packages/taler-wallet-webextension/src/cta/Refund.stories.tsx 
b/packages/taler-wallet-webextension/src/cta/Refund.stories.tsx
index 88e714cb..a0abcea5 100644
--- a/packages/taler-wallet-webextension/src/cta/Refund.stories.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Refund.stories.tsx
@@ -15,63 +15,61 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { OrderShortInfo } from '@gnu-taler/taler-util';
-import { createExample } from '../test-utils';
-import { View as TestedComponent } from './Refund';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
+import { OrderShortInfo } from "@gnu-taler/taler-util";
+import { createExample } from "../test-utils";
+import { View as TestedComponent } from "./Refund";
 
 export default {
-  title: 'cta/refund',
+  title: "cta/refund",
   component: TestedComponent,
-  argTypes: {
-  },
+  argTypes: {},
 };
 
 export const Complete = createExample(TestedComponent, {
   applyResult: {
-    amountEffectivePaid: 'USD:10',
-    amountRefundGone: 'USD:0',
-    amountRefundGranted: 'USD:2',
-    contractTermsHash: 'QWEASDZXC',
-    info: {
-      summary: 'tasty cold beer',
-      contractTermsHash: 'QWEASDZXC',
-    } as Partial<OrderShortInfo> as any,
+    amountEffectivePaid: "USD:10",
+    amountRefundGone: "USD:0",
+    amountRefundGranted: "USD:2",
+    contractTermsHash: "QWEASDZXC",
+    info: ({
+      summary: "tasty cold beer",
+      contractTermsHash: "QWEASDZXC",
+    } as Partial<OrderShortInfo>) as any,
     pendingAtExchange: false,
     proposalId: "proposal123",
-  }
+  },
 });
 
 export const Partial = createExample(TestedComponent, {
   applyResult: {
-    amountEffectivePaid: 'USD:10',
-    amountRefundGone: 'USD:1',
-    amountRefundGranted: 'USD:2',
-    contractTermsHash: 'QWEASDZXC',
-    info: {
-      summary: 'tasty cold beer',
-      contractTermsHash: 'QWEASDZXC',
-    } as Partial<OrderShortInfo> as any,
+    amountEffectivePaid: "USD:10",
+    amountRefundGone: "USD:1",
+    amountRefundGranted: "USD:2",
+    contractTermsHash: "QWEASDZXC",
+    info: ({
+      summary: "tasty cold beer",
+      contractTermsHash: "QWEASDZXC",
+    } as Partial<OrderShortInfo>) as any,
     pendingAtExchange: false,
     proposalId: "proposal123",
-  }
+  },
 });
 
 export const InProgress = createExample(TestedComponent, {
   applyResult: {
-    amountEffectivePaid: 'USD:10',
-    amountRefundGone: 'USD:1',
-    amountRefundGranted: 'USD:2',
-    contractTermsHash: 'QWEASDZXC',
-    info: {
-      summary: 'tasty cold beer',
-      contractTermsHash: 'QWEASDZXC',
-    } as Partial<OrderShortInfo> as any,
+    amountEffectivePaid: "USD:10",
+    amountRefundGone: "USD:1",
+    amountRefundGranted: "USD:2",
+    contractTermsHash: "QWEASDZXC",
+    info: ({
+      summary: "tasty cold beer",
+      contractTermsHash: "QWEASDZXC",
+    } as Partial<OrderShortInfo>) as any,
     pendingAtExchange: true,
     proposalId: "proposal123",
-  }
+  },
 });
diff --git a/packages/taler-wallet-webextension/src/cta/Refund.tsx 
b/packages/taler-wallet-webextension/src/cta/Refund.tsx
index 94309536..aa11dca6 100644
--- a/packages/taler-wallet-webextension/src/cta/Refund.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Refund.tsx
@@ -22,45 +22,46 @@
 
 import * as wxApi from "../wxApi";
 import { AmountView } from "../renderHtml";
-import {
-  ApplyRefundResponse,
-  Amounts,
-} from "@gnu-taler/taler-util";
+import { ApplyRefundResponse, Amounts } from "@gnu-taler/taler-util";
 import { useEffect, useState } from "preact/hooks";
 import { JSX } from "preact/jsx-runtime";
-import { h } from 'preact';
+import { h } from "preact";
 
 interface Props {
-  talerRefundUri?: string
+  talerRefundUri?: string;
 }
 export interface ViewProps {
   applyResult: ApplyRefundResponse;
 }
 export function View({ applyResult }: ViewProps) {
-  return <section class="main">
-    <h1>GNU Taler Wallet</h1>
-    <article class="fade">
-      <h2>Refund Status</h2>
-      <p>
-        The product <em>{applyResult.info.summary}</em> has received a total
-        effective refund of{" "}
-        <AmountView amount={applyResult.amountRefundGranted} />.
-      </p>
-      {applyResult.pendingAtExchange ? (
-        <p>Refund processing is still in progress.</p>
-      ) : null}
-      {!Amounts.isZero(applyResult.amountRefundGone) ? (
+  return (
+    <section class="main">
+      <h1>GNU Taler Wallet</h1>
+      <article class="fade">
+        <h2>Refund Status</h2>
         <p>
-          The refund amount of{" "}
-          <AmountView amount={applyResult.amountRefundGone} />{" "}
-          could not be applied.
+          The product <em>{applyResult.info.summary}</em> has received a total
+          effective refund of{" "}
+          <AmountView amount={applyResult.amountRefundGranted} />.
         </p>
-      ) : null}
-    </article>
-  </section>
+        {applyResult.pendingAtExchange ? (
+          <p>Refund processing is still in progress.</p>
+        ) : null}
+        {!Amounts.isZero(applyResult.amountRefundGone) ? (
+          <p>
+            The refund amount of{" "}
+            <AmountView amount={applyResult.amountRefundGone} /> could not be
+            applied.
+          </p>
+        ) : null}
+      </article>
+    </section>
+  );
 }
 export function RefundPage({ talerRefundUri }: Props): JSX.Element {
-  const [applyResult, setApplyResult] = useState<ApplyRefundResponse | 
undefined>(undefined);
+  const [applyResult, setApplyResult] = useState<
+    ApplyRefundResponse | undefined
+  >(undefined);
   const [errMsg, setErrMsg] = useState<string | undefined>(undefined);
 
   useEffect(() => {
diff --git a/packages/taler-wallet-webextension/src/cta/Tip.stories.tsx 
b/packages/taler-wallet-webextension/src/cta/Tip.stories.tsx
index 389b183f..8da59951 100644
--- a/packages/taler-wallet-webextension/src/cta/Tip.stories.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Tip.stories.tsx
@@ -15,45 +15,43 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { createExample } from '../test-utils';
-import { View as TestedComponent } from './Tip';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
+import { createExample } from "../test-utils";
+import { View as TestedComponent } from "./Tip";
 
 export default {
-  title: 'cta/tip',
+  title: "cta/tip",
   component: TestedComponent,
-  argTypes: {
-  },
+  argTypes: {},
 };
 
 export const Accepted = createExample(TestedComponent, {
   prepareTipResult: {
     accepted: true,
-    merchantBaseUrl: '',
-    exchangeBaseUrl: '',
-    expirationTimestamp : {
-      t_ms: 0
+    merchantBaseUrl: "",
+    exchangeBaseUrl: "",
+    expirationTimestamp: {
+      t_ms: 0,
     },
-    tipAmountEffective: 'USD:10',
-    tipAmountRaw: 'USD:5',
-    walletTipId: 'id'
-  }
+    tipAmountEffective: "USD:10",
+    tipAmountRaw: "USD:5",
+    walletTipId: "id",
+  },
 });
 
 export const NotYetAccepted = createExample(TestedComponent, {
   prepareTipResult: {
     accepted: false,
-    merchantBaseUrl: 'http://merchant.url/',
-    exchangeBaseUrl: 'http://exchange.url/',
-    expirationTimestamp : {
-      t_ms: 0
+    merchantBaseUrl: "http://merchant.url/";,
+    exchangeBaseUrl: "http://exchange.url/";,
+    expirationTimestamp: {
+      t_ms: 0,
     },
-    tipAmountEffective: 'USD:10',
-    tipAmountRaw: 'USD:5',
-    walletTipId: 'id'
-  }
+    tipAmountEffective: "USD:10",
+    tipAmountRaw: "USD:5",
+    walletTipId: "id",
+  },
 });
diff --git a/packages/taler-wallet-webextension/src/cta/Tip.tsx 
b/packages/taler-wallet-webextension/src/cta/Tip.tsx
index dc1feaed..0a1c1238 100644
--- a/packages/taler-wallet-webextension/src/cta/Tip.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Tip.tsx
@@ -25,43 +25,43 @@ import { PrepareTipResult } from "@gnu-taler/taler-util";
 import { AmountView } from "../renderHtml";
 import * as wxApi from "../wxApi";
 import { JSX } from "preact/jsx-runtime";
-import { h } from 'preact';
+import { h } from "preact";
 
 interface Props {
-  talerTipUri?: string
+  talerTipUri?: string;
 }
 export interface ViewProps {
   prepareTipResult: PrepareTipResult;
   onAccept: () => void;
   onIgnore: () => void;
-
 }
 export function View({ prepareTipResult, onAccept, onIgnore }: ViewProps) {
-  return <section class="main">
-    <h1>GNU Taler Wallet</h1>
-    <article class="fade">
-      {prepareTipResult.accepted ? (
-        <span>
-          Tip from <code>{prepareTipResult.merchantBaseUrl}</code> accepted. 
Check
-        your transactions list for more details.
-        </span>
-      ) : (
+  return (
+    <section class="main">
+      <h1>GNU Taler Wallet</h1>
+      <article class="fade">
+        {prepareTipResult.accepted ? (
+          <span>
+            Tip from <code>{prepareTipResult.merchantBaseUrl}</code> accepted.
+            Check your transactions list for more details.
+          </span>
+        ) : (
           <div>
             <p>
               The merchant <code>{prepareTipResult.merchantBaseUrl}</code> is
-            offering you a tip of{" "}
+              offering you a tip of{" "}
               <strong>
                 <AmountView amount={prepareTipResult.tipAmountEffective} />
               </strong>{" "}
-            via the exchange <code>{prepareTipResult.exchangeBaseUrl}</code>
+              via the exchange <code>{prepareTipResult.exchangeBaseUrl}</code>
             </p>
             <button onClick={onAccept}>Accept tip</button>
             <button onClick={onIgnore}>Ignore</button>
           </div>
         )}
-    </article>
-  </section>
-
+      </article>
+    </section>
+  );
 }
 
 export function TipPage({ talerTipUri }: Props): JSX.Element {
@@ -105,7 +105,11 @@ export function TipPage({ talerTipUri }: Props): 
JSX.Element {
     return <span>Loading ...</span>;
   }
 
-  return <View prepareTipResult={prepareTipResult}
-    onAccept={doAccept} onIgnore={doIgnore}
-  />
+  return (
+    <View
+      prepareTipResult={prepareTipResult}
+      onAccept={doAccept}
+      onIgnore={doIgnore}
+    />
+  );
 }
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx 
b/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx
index 5e29a3e3..90df2a27 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx
@@ -15,23 +15,22 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { amountFractionalBase, Amounts } from '@gnu-taler/taler-util';
-import { ExchangeRecord } from '@gnu-taler/taler-wallet-core';
-import { ExchangeWithdrawDetails } from 
'@gnu-taler/taler-wallet-core/src/operations/withdraw';
-import { getMaxListeners } from 'process';
-import { createExample } from '../test-utils';
-import { View as TestedComponent } from './Withdraw';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
+import { amountFractionalBase, Amounts } from "@gnu-taler/taler-util";
+import { ExchangeRecord } from "@gnu-taler/taler-wallet-core";
+import { ExchangeWithdrawDetails } from 
"@gnu-taler/taler-wallet-core/src/operations/withdraw";
+import { getMaxListeners } from "process";
+import { createExample } from "../test-utils";
+import { View as TestedComponent } from "./Withdraw";
 
 export default {
-  title: 'cta/withdraw',
+  title: "cta/withdraw",
   component: TestedComponent,
   argTypes: {
-    onSwitchExchange: { action: 'onRetry' },
+    onSwitchExchange: { action: "onRetry" },
   },
 };
 
@@ -48,7 +47,7 @@ const termsHtml = `<html xmlns="http://www.w3.org/1999/xhtml"; 
lang="en">
   </div>
 </body>
 </html>
-`
+`;
 const termsPlain = `
 Terms Of Service
 ****************
@@ -432,7 +431,7 @@ Questions or comments
 We welcome comments, questions, concerns, or suggestions. Please send
 us a message on our contact page at legal@taler-systems.com.
 
-`
+`;
 
 const termsXml = `<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE document PUBLIC "+//IDN docutils.sourceforge.net//DTD Docutils 
Generic//EN//XML" "http://docutils.sourceforge.net/docs/ref/docutils.dtd";>
@@ -781,120 +780,131 @@ const termsXml = `<?xml version="1.0" encoding="utf-8"?>
 `;
 
 export const NewTerms = createExample(TestedComponent, {
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.demo.taler.net',
-    paytoUris: ['asd'],
-  }, {
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.test.taler.net',
-    paytoUris: ['asd'],
-  }],
-  exchangeBaseUrl: 'exchange.demo.taler.net',
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.demo.taler.net",
+      paytoUris: ["asd"],
+    },
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.test.taler.net",
+      paytoUris: ["asd"],
+    },
+  ],
+  exchangeBaseUrl: "exchange.demo.taler.net",
   details: {
-    content: '',
-    contentType: '',
-    currentEtag: '',
+    content: "",
+    contentType: "",
+    currentEtag: "",
     acceptedEtag: undefined,
   },
   withdrawalFee: {
-    currency: 'USD',
+    currency: "USD",
     fraction: 0,
-    value: 0
+    value: 0,
   },
   amount: {
-    currency: 'USD',
+    currency: "USD",
     value: 2,
-    fraction: 10000000
+    fraction: 10000000,
   },
 
-  onSwitchExchange: async () => { },
+  onSwitchExchange: async () => {},
   terms: {
     value: {
-      type: 'xml',
+      type: "xml",
       document: new DOMParser().parseFromString(termsXml, "text/xml"),
     },
-    status: 'new'
+    status: "new",
   },
-})
+});
 
 export const TermsReviewingPLAIN = createExample(TestedComponent, {
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.demo.taler.net',
-    paytoUris: ['asd'],
-  }, {
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.test.taler.net',
-    paytoUris: ['asd'],
-  }],
-  exchangeBaseUrl: 'exchange.demo.taler.net',
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.demo.taler.net",
+      paytoUris: ["asd"],
+    },
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.test.taler.net",
+      paytoUris: ["asd"],
+    },
+  ],
+  exchangeBaseUrl: "exchange.demo.taler.net",
   details: {
-    content: '',
-    contentType: '',
-    currentEtag: '',
+    content: "",
+    contentType: "",
+    currentEtag: "",
     acceptedEtag: undefined,
   },
   withdrawalFee: {
-    currency: 'USD',
+    currency: "USD",
     fraction: 0,
-    value: 0
+    value: 0,
   },
   amount: {
-    currency: 'USD',
+    currency: "USD",
     value: 2,
-    fraction: 10000000
+    fraction: 10000000,
   },
 
-  onSwitchExchange: async () => { },
+  onSwitchExchange: async () => {},
   terms: {
     value: {
-      type: 'plain',
-      content: termsPlain
+      type: "plain",
+      content: termsPlain,
     },
-    status: 'new'
+    status: "new",
   },
-  reviewing: true
-})
+  reviewing: true,
+});
 
 export const TermsReviewingHTML = createExample(TestedComponent, {
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.demo.taler.net',
-    paytoUris: ['asd'],
-  }, {
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.test.taler.net',
-    paytoUris: ['asd'],
-  }],
-  exchangeBaseUrl: 'exchange.demo.taler.net',
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.demo.taler.net",
+      paytoUris: ["asd"],
+    },
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.test.taler.net",
+      paytoUris: ["asd"],
+    },
+  ],
+  exchangeBaseUrl: "exchange.demo.taler.net",
   details: {
-    content: '',
-    contentType: '',
-    currentEtag: '',
+    content: "",
+    contentType: "",
+    currentEtag: "",
     acceptedEtag: undefined,
   },
   withdrawalFee: {
-    currency: 'USD',
+    currency: "USD",
     fraction: 0,
-    value: 0
+    value: 0,
   },
   amount: {
-    currency: 'USD',
+    currency: "USD",
     value: 2,
-    fraction: 10000000
+    fraction: 10000000,
   },
 
-  onSwitchExchange: async () => { },
+  onSwitchExchange: async () => {},
   terms: {
     value: {
-      type: 'html',
-      href: new 
URL(`data:text/html;base64,${Buffer.from(termsHtml).toString('base64')}`),
+      type: "html",
+      href: new URL(
+        `data:text/html;base64,${Buffer.from(termsHtml).toString("base64")}`,
+      ),
     },
-    status: 'new'
+    status: "new",
   },
-  reviewing: true
-})
+  reviewing: true,
+});
 
 const termsPdf = `
 %PDF-1.2 
@@ -909,306 +919,330 @@ endobj
 trailer
 << /Root 3 0 R >>
 %%EOF
-`
+`;
 
 export const TermsReviewingPDF = createExample(TestedComponent, {
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.demo.taler.net',
-    paytoUris: ['asd'],
-  }, {
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.test.taler.net',
-    paytoUris: ['asd'],
-  }],
-  exchangeBaseUrl: 'exchange.demo.taler.net',
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.demo.taler.net",
+      paytoUris: ["asd"],
+    },
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.test.taler.net",
+      paytoUris: ["asd"],
+    },
+  ],
+  exchangeBaseUrl: "exchange.demo.taler.net",
   details: {
-    content: '',
-    contentType: '',
-    currentEtag: '',
+    content: "",
+    contentType: "",
+    currentEtag: "",
     acceptedEtag: undefined,
   },
   withdrawalFee: {
-    currency: 'USD',
+    currency: "USD",
     fraction: 0,
-    value: 0
+    value: 0,
   },
   amount: {
-    currency: 'USD',
+    currency: "USD",
     value: 2,
-    fraction: 10000000
+    fraction: 10000000,
   },
 
-  onSwitchExchange: async () => { },
+  onSwitchExchange: async () => {},
   terms: {
     value: {
-      type: 'pdf',
-      location: new 
URL(`data:text/html;base64,${Buffer.from(termsPdf).toString('base64')}`),
+      type: "pdf",
+      location: new URL(
+        `data:text/html;base64,${Buffer.from(termsPdf).toString("base64")}`,
+      ),
     },
-    status: 'new'
+    status: "new",
   },
-  reviewing: true
-})
-
+  reviewing: true,
+});
 
 export const TermsReviewingXML = createExample(TestedComponent, {
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.demo.taler.net',
-    paytoUris: ['asd'],
-  }, {
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.test.taler.net',
-    paytoUris: ['asd'],
-  }],
-  exchangeBaseUrl: 'exchange.demo.taler.net',
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.demo.taler.net",
+      paytoUris: ["asd"],
+    },
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.test.taler.net",
+      paytoUris: ["asd"],
+    },
+  ],
+  exchangeBaseUrl: "exchange.demo.taler.net",
   details: {
-    content: '',
-    contentType: '',
-    currentEtag: '',
+    content: "",
+    contentType: "",
+    currentEtag: "",
     acceptedEtag: undefined,
   },
   withdrawalFee: {
-    currency: 'USD',
+    currency: "USD",
     fraction: 0,
-    value: 0
+    value: 0,
   },
   amount: {
-    currency: 'USD',
+    currency: "USD",
     value: 2,
-    fraction: 10000000
+    fraction: 10000000,
   },
 
-  onSwitchExchange: async () => { },
+  onSwitchExchange: async () => {},
   terms: {
     value: {
-      type: 'xml',
+      type: "xml",
       document: new DOMParser().parseFromString(termsXml, "text/xml"),
     },
-    status: 'new'
+    status: "new",
   },
-  reviewing: true
-})
+  reviewing: true,
+});
 
 export const NewTermsAccepted = createExample(TestedComponent, {
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.demo.taler.net',
-    paytoUris: ['asd'],
-  }, {
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.test.taler.net',
-    paytoUris: ['asd'],
-  }],
-  exchangeBaseUrl: 'exchange.demo.taler.net',
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.demo.taler.net",
+      paytoUris: ["asd"],
+    },
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.test.taler.net",
+      paytoUris: ["asd"],
+    },
+  ],
+  exchangeBaseUrl: "exchange.demo.taler.net",
   details: {
-    content: '',
-    contentType: '',
-    currentEtag: '',
+    content: "",
+    contentType: "",
+    currentEtag: "",
     acceptedEtag: undefined,
   },
   withdrawalFee: {
-    currency: 'USD',
+    currency: "USD",
     fraction: 0,
-    value: 0
+    value: 0,
   },
   amount: {
-    currency: 'USD',
+    currency: "USD",
     value: 2,
-    fraction: 10000000
+    fraction: 10000000,
   },
-  onSwitchExchange: async () => { },
+  onSwitchExchange: async () => {},
   terms: {
     value: {
-      type: 'xml',
+      type: "xml",
       document: new DOMParser().parseFromString(termsXml, "text/xml"),
     },
-    status: 'new'
+    status: "new",
   },
-  reviewed: true
-})
+  reviewed: true,
+});
 
 export const TermsShowAgainXML = createExample(TestedComponent, {
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.demo.taler.net',
-    paytoUris: ['asd'],
-  }, {
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.test.taler.net',
-    paytoUris: ['asd'],
-  }],
-  exchangeBaseUrl: 'exchange.demo.taler.net',
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.demo.taler.net",
+      paytoUris: ["asd"],
+    },
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.test.taler.net",
+      paytoUris: ["asd"],
+    },
+  ],
+  exchangeBaseUrl: "exchange.demo.taler.net",
   details: {
-    content: '',
-    contentType: '',
-    currentEtag: '',
+    content: "",
+    contentType: "",
+    currentEtag: "",
     acceptedEtag: undefined,
   },
   withdrawalFee: {
-    currency: 'USD',
+    currency: "USD",
     fraction: 0,
-    value: 0
+    value: 0,
   },
   amount: {
-    currency: 'USD',
+    currency: "USD",
     value: 2,
-    fraction: 10000000
+    fraction: 10000000,
   },
 
-  onSwitchExchange: async () => { },
+  onSwitchExchange: async () => {},
   terms: {
     value: {
-      type: 'xml',
+      type: "xml",
       document: new DOMParser().parseFromString(termsXml, "text/xml"),
     },
-    status: 'new'
+    status: "new",
   },
   reviewed: true,
   reviewing: true,
-})
+});
 
 export const TermsChanged = createExample(TestedComponent, {
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.demo.taler.net',
-    paytoUris: ['asd'],
-  }, {
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.test.taler.net',
-    paytoUris: ['asd'],
-  }],
-  exchangeBaseUrl: 'exchange.demo.taler.net',
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.demo.taler.net",
+      paytoUris: ["asd"],
+    },
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.test.taler.net",
+      paytoUris: ["asd"],
+    },
+  ],
+  exchangeBaseUrl: "exchange.demo.taler.net",
   details: {
-    content: '',
-    contentType: '',
-    currentEtag: '',
+    content: "",
+    contentType: "",
+    currentEtag: "",
     acceptedEtag: undefined,
   },
   withdrawalFee: {
-    currency: 'USD',
+    currency: "USD",
     fraction: 0,
-    value: 0
+    value: 0,
   },
   amount: {
-    currency: 'USD',
+    currency: "USD",
     value: 2,
-    fraction: 10000000
+    fraction: 10000000,
   },
 
-  onSwitchExchange: async () => { },
+  onSwitchExchange: async () => {},
   terms: {
     value: {
-      type: 'xml',
+      type: "xml",
       document: new DOMParser().parseFromString(termsXml, "text/xml"),
     },
-    status: 'changed'
+    status: "changed",
   },
-})
+});
 
 export const TermsNotFound = createExample(TestedComponent, {
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.demo.taler.net',
-    paytoUris: ['asd'],
-  }, {
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.test.taler.net',
-    paytoUris: ['asd'],
-  }],
-  exchangeBaseUrl: 'exchange.demo.taler.net',
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.demo.taler.net",
+      paytoUris: ["asd"],
+    },
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.test.taler.net",
+      paytoUris: ["asd"],
+    },
+  ],
+  exchangeBaseUrl: "exchange.demo.taler.net",
   details: {
-    content: '',
-    contentType: '',
-    currentEtag: '',
+    content: "",
+    contentType: "",
+    currentEtag: "",
     acceptedEtag: undefined,
   },
   withdrawalFee: {
-    currency: 'USD',
+    currency: "USD",
     fraction: 0,
-    value: 0
+    value: 0,
   },
   amount: {
-    currency: 'USD',
+    currency: "USD",
     value: 2,
-    fraction: 10000000
+    fraction: 10000000,
   },
 
-  onSwitchExchange: async () => { },
+  onSwitchExchange: async () => {},
   terms: {
-    status: 'notfound'
+    status: "notfound",
   },
-})
+});
 
 export const TermsAlreadyAccepted = createExample(TestedComponent, {
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.demo.taler.net',
-    paytoUris: ['asd'],
-  }, {
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.test.taler.net',
-    paytoUris: ['asd'],
-  }],
-  exchangeBaseUrl: 'exchange.demo.taler.net',
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.demo.taler.net",
+      paytoUris: ["asd"],
+    },
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.test.taler.net",
+      paytoUris: ["asd"],
+    },
+  ],
+  exchangeBaseUrl: "exchange.demo.taler.net",
   details: {
-    content: '',
-    contentType: '',
-    currentEtag: '',
+    content: "",
+    contentType: "",
+    currentEtag: "",
     acceptedEtag: undefined,
   },
   withdrawalFee: {
-    currency: 'USD',
+    currency: "USD",
     fraction: amountFractionalBase * 0.5,
-    value: 0
+    value: 0,
   },
   amount: {
-    currency: 'USD',
+    currency: "USD",
     value: 2,
-    fraction: 10000000
+    fraction: 10000000,
   },
 
-  onSwitchExchange: async () => { },
+  onSwitchExchange: async () => {},
   terms: {
-    status: 'accepted'
+    status: "accepted",
   },
-})
-
+});
 
 export const WithoutFee = createExample(TestedComponent, {
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.demo.taler.net',
-    paytoUris: ['asd'],
-  }, {
-    currency: 'USD',
-    exchangeBaseUrl: 'exchange.test.taler.net',
-    paytoUris: ['asd'],
-  }],
-  exchangeBaseUrl: 'exchange.demo.taler.net',
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.demo.taler.net",
+      paytoUris: ["asd"],
+    },
+    {
+      currency: "USD",
+      exchangeBaseUrl: "exchange.test.taler.net",
+      paytoUris: ["asd"],
+    },
+  ],
+  exchangeBaseUrl: "exchange.demo.taler.net",
   details: {
-    content: '',
-    contentType: '',
-    currentEtag: '',
+    content: "",
+    contentType: "",
+    currentEtag: "",
     acceptedEtag: undefined,
   },
   withdrawalFee: {
-    currency: 'USD',
+    currency: "USD",
     fraction: 0,
     value: 0,
   },
   amount: {
-    currency: 'USD',
+    currency: "USD",
     value: 2,
-    fraction: 10000000
+    fraction: 10000000,
   },
 
-  onSwitchExchange: async () => { },
+  onSwitchExchange: async () => {},
   terms: {
     value: {
-      type: 'xml',
+      type: "xml",
       document: new DOMParser().parseFromString(termsXml, "text/xml"),
     },
-    status: 'accepted',
-  }
-})
\ No newline at end of file
+    status: "accepted",
+  },
+});
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx 
b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
index 6ef72cbe..603dafcd 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
@@ -21,21 +21,39 @@
  * @author Florian Dold
  */
 
-import { AmountJson, Amounts, ExchangeListItem, GetExchangeTosResult, i18n, 
WithdrawUriInfoResponse } from '@gnu-taler/taler-util';
-import { ExchangeWithdrawDetails } from 
'@gnu-taler/taler-wallet-core/src/operations/withdraw';
+import {
+  AmountJson,
+  Amounts,
+  ExchangeListItem,
+  GetExchangeTosResult,
+  i18n,
+  WithdrawUriInfoResponse,
+} from "@gnu-taler/taler-util";
+import { VNode, h } from "preact";
 import { useState } from "preact/hooks";
-import { Fragment } from 'preact/jsx-runtime';
-import { CheckboxOutlined } from '../components/CheckboxOutlined';
-import { ExchangeXmlTos } from '../components/ExchangeToS';
-import { LogoHeader } from '../components/LogoHeader';
-import { Part } from '../components/Part';
-import { SelectList } from '../components/SelectList';
-import { ButtonSuccess, ButtonWarning, LinkSuccess, LinkWarning, 
TermsOfService, WalletAction, WarningText } from '../components/styled';
-import { useAsyncAsHook } from '../hooks/useAsyncAsHook';
+import { Fragment } from "preact/jsx-runtime";
+import { CheckboxOutlined } from "../components/CheckboxOutlined";
+import { ExchangeXmlTos } from "../components/ExchangeToS";
+import { LogoHeader } from "../components/LogoHeader";
+import { Part } from "../components/Part";
+import { SelectList } from "../components/SelectList";
+import {
+  ButtonSuccess,
+  ButtonWarning,
+  LinkSuccess,
+  TermsOfService,
+  WalletAction,
+  WarningText,
+} from "../components/styled";
+import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
 import {
-  acceptWithdrawal, getExchangeWithdrawalInfo, getWithdrawalDetailsForUri, 
setExchangeTosAccepted, listExchanges, getExchangeTos
+  acceptWithdrawal,
+  getExchangeTos,
+  getExchangeWithdrawalInfo,
+  getWithdrawalDetailsForUri,
+  listExchanges,
+  setExchangeTosAccepted,
 } from "../wxApi";
-import { wxMain } from '../wxBackend.js';
 
 interface Props {
   talerWithdrawUri?: string;
@@ -58,145 +76,193 @@ export interface ViewProps {
     status: TermsStatus;
   };
   knownExchanges: ExchangeListItem[];
+}
 
-};
-
-type TermsStatus = 'new' | 'accepted' | 'changed' | 'notfound';
+type TermsStatus = "new" | "accepted" | "changed" | "notfound";
 
-type TermsDocument = TermsDocumentXml | TermsDocumentHtml | TermsDocumentPlain 
| TermsDocumentJson | TermsDocumentPdf;
+type TermsDocument =
+  | TermsDocumentXml
+  | TermsDocumentHtml
+  | TermsDocumentPlain
+  | TermsDocumentJson
+  | TermsDocumentPdf;
 
 interface TermsDocumentXml {
-  type: 'xml',
-  document: Document,
+  type: "xml";
+  document: Document;
 }
 
 interface TermsDocumentHtml {
-  type: 'html',
-  href: URL,
+  type: "html";
+  href: URL;
 }
 
 interface TermsDocumentPlain {
-  type: 'plain',
-  content: string,
+  type: "plain";
+  content: string;
 }
 
 interface TermsDocumentJson {
-  type: 'json',
-  data: any,
+  type: "json";
+  data: any;
 }
 
 interface TermsDocumentPdf {
-  type: 'pdf',
-  location: URL,
+  type: "pdf";
+  location: URL;
 }
 
 function amountToString(text: AmountJson) {
-  const aj = Amounts.jsonifyAmount(text)
-  const amount = Amounts.stringifyValue(aj)
-  return `${amount} ${aj.currency}`
+  const aj = Amounts.jsonifyAmount(text);
+  const amount = Amounts.stringifyValue(aj);
+  return `${amount} ${aj.currency}`;
 }
 
-export function View({ details, withdrawalFee, exchangeBaseUrl, 
knownExchanges, amount, onWithdraw, onSwitchExchange, terms, reviewing, 
onReview, onAccept, reviewed, confirmed }: ViewProps) {
-  const needsReview = terms.status === 'changed' || terms.status === 'new'
-
-  const [switchingExchange, setSwitchingExchange] = useState<string | 
undefined>(undefined)
-  const exchanges = knownExchanges.reduce((prev, ex) => ({ ...prev, 
[ex.exchangeBaseUrl]: ex.exchangeBaseUrl }), {})
+export function View({
+  details,
+  withdrawalFee,
+  exchangeBaseUrl,
+  knownExchanges,
+  amount,
+  onWithdraw,
+  onSwitchExchange,
+  terms,
+  reviewing,
+  onReview,
+  onAccept,
+  reviewed,
+  confirmed,
+}: ViewProps) {
+  const needsReview = terms.status === "changed" || terms.status === "new";
+
+  const [switchingExchange, setSwitchingExchange] = useState<
+    string | undefined
+  >(undefined);
+  const exchanges = knownExchanges.reduce(
+    (prev, ex) => ({ ...prev, [ex.exchangeBaseUrl]: ex.exchangeBaseUrl }),
+    {},
+  );
 
   return (
     <WalletAction>
       <LogoHeader />
-      <h2>
-        {i18n.str`Digital cash withdrawal`}
-      </h2>
+      <h2>{i18n.str`Digital cash withdrawal`}</h2>
       <section>
-        <Part title="Total to withdraw" 
text={amountToString(Amounts.sub(amount, withdrawalFee).amount)} 
kind='positive' />
-        <Part title="Chosen amount" text={amountToString(amount)} 
kind='neutral' />
-        {Amounts.isNonZero(withdrawalFee) &&
-          <Part title="Exchange fee" text={amountToString(withdrawalFee)} 
kind='negative' />
-        }
-        <Part title="Exchange" text={exchangeBaseUrl} kind='neutral' big />
+        <Part
+          title="Total to withdraw"
+          text={amountToString(Amounts.sub(amount, withdrawalFee).amount)}
+          kind="positive"
+        />
+        <Part
+          title="Chosen amount"
+          text={amountToString(amount)}
+          kind="neutral"
+        />
+        {Amounts.isNonZero(withdrawalFee) && (
+          <Part
+            title="Exchange fee"
+            text={amountToString(withdrawalFee)}
+            kind="negative"
+          />
+        )}
+        <Part title="Exchange" text={exchangeBaseUrl} kind="neutral" big />
       </section>
-      {!reviewing &&
+      {!reviewing && (
         <section>
-          {switchingExchange !== undefined ? <Fragment>
-            <div>
-              <SelectList label="Known exchanges" list={exchanges} name="" 
onChange={onSwitchExchange} />
-            </div>
-            <LinkSuccess upperCased onClick={() => 
onSwitchExchange(switchingExchange)}>
-              {i18n.str`Confirm exchange selection`}
-            </LinkSuccess>
-          </Fragment>
-            : <LinkSuccess upperCased onClick={() => setSwitchingExchange("")}>
+          {switchingExchange !== undefined ? (
+            <Fragment>
+              <div>
+                <SelectList
+                  label="Known exchanges"
+                  list={exchanges}
+                  name=""
+                  onChange={onSwitchExchange}
+                />
+              </div>
+              <LinkSuccess
+                upperCased
+                onClick={() => onSwitchExchange(switchingExchange)}
+              >
+                {i18n.str`Confirm exchange selection`}
+              </LinkSuccess>
+            </Fragment>
+          ) : (
+            <LinkSuccess upperCased onClick={() => setSwitchingExchange("")}>
               {i18n.str`Switch exchange`}
-            </LinkSuccess>}
-
+            </LinkSuccess>
+          )}
         </section>
-      }
-      {!reviewing && reviewed &&
+      )}
+      {!reviewing && reviewed && (
         <section>
-          <LinkSuccess
-            upperCased
-            onClick={() => onReview(true)}
-          >
+          <LinkSuccess upperCased onClick={() => onReview(true)}>
             {i18n.str`Show terms of service`}
           </LinkSuccess>
         </section>
-      }
-      {terms.status === 'notfound' &&
+      )}
+      {terms.status === "notfound" && (
         <section>
           <WarningText>
             {i18n.str`Exchange doesn't have terms of service`}
           </WarningText>
         </section>
-      }
-      {reviewing &&
+      )}
+      {reviewing && (
         <section>
-          {terms.status !== 'accepted' && terms.value && terms.value.type === 
'xml' &&
-            <TermsOfService>
-              <ExchangeXmlTos doc={terms.value.document} />
-            </TermsOfService>
-          }
-          {terms.status !== 'accepted' && terms.value && terms.value.type === 
'plain' &&
-            <div style={{ textAlign: 'left' }}>
-              <pre>{terms.value.content}</pre>
-            </div>
-          }
-          {terms.status !== 'accepted' && terms.value && terms.value.type === 
'html' &&
-            <iframe src={terms.value.href.toString()} />
-          }
-          {terms.status !== 'accepted' && terms.value && terms.value.type === 
'pdf' &&
-            <a href={terms.value.location.toString()} download="tos.pdf" 
>Download Terms of Service</a>
-          }
-        </section>}
-      {reviewing && reviewed &&
+          {terms.status !== "accepted" &&
+            terms.value &&
+            terms.value.type === "xml" && (
+              <TermsOfService>
+                <ExchangeXmlTos doc={terms.value.document} />
+              </TermsOfService>
+            )}
+          {terms.status !== "accepted" &&
+            terms.value &&
+            terms.value.type === "plain" && (
+              <div style={{ textAlign: "left" }}>
+                <pre>{terms.value.content}</pre>
+              </div>
+            )}
+          {terms.status !== "accepted" &&
+            terms.value &&
+            terms.value.type === "html" && (
+              <iframe src={terms.value.href.toString()} />
+            )}
+          {terms.status !== "accepted" &&
+            terms.value &&
+            terms.value.type === "pdf" && (
+              <a href={terms.value.location.toString()} download="tos.pdf">
+                Download Terms of Service
+              </a>
+            )}
+        </section>
+      )}
+      {reviewing && reviewed && (
         <section>
-          <LinkSuccess
-            upperCased
-            onClick={() => onReview(false)}
-          >
+          <LinkSuccess upperCased onClick={() => onReview(false)}>
             {i18n.str`Hide terms of service`}
           </LinkSuccess>
         </section>
-      }
-      {(reviewing || reviewed) &&
+      )}
+      {(reviewing || reviewed) && (
         <section>
           <CheckboxOutlined
             name="terms"
             enabled={reviewed}
             label={i18n.str`I accept the exchange terms of service`}
             onToggle={() => {
-              onAccept(!reviewed)
-              onReview(false)
+              onAccept(!reviewed);
+              onReview(false);
             }}
           />
         </section>
-      }
+      )}
 
       {/**
        * Main action section
        */}
       <section>
-        {terms.status === 'new' && !reviewed && !reviewing &&
+        {terms.status === "new" && !reviewed && !reviewing && (
           <ButtonSuccess
             upperCased
             disabled={!exchangeBaseUrl}
@@ -204,8 +270,8 @@ export function View({ details, withdrawalFee, 
exchangeBaseUrl, knownExchanges,
           >
             {i18n.str`Review exchange terms of service`}
           </ButtonSuccess>
-        }
-        {terms.status === 'changed' && !reviewed && !reviewing &&
+        )}
+        {terms.status === "changed" && !reviewed && !reviewing && (
           <ButtonWarning
             upperCased
             disabled={!exchangeBaseUrl}
@@ -213,8 +279,8 @@ export function View({ details, withdrawalFee, 
exchangeBaseUrl, knownExchanges,
           >
             {i18n.str`Review new version of terms of service`}
           </ButtonWarning>
-        }
-        {(terms.status === 'accepted' || (needsReview && reviewed)) &&
+        )}
+        {(terms.status === "accepted" || (needsReview && reviewed)) && (
           <ButtonSuccess
             upperCased
             disabled={!exchangeBaseUrl || confirmed}
@@ -222,8 +288,8 @@ export function View({ details, withdrawalFee, 
exchangeBaseUrl, knownExchanges,
           >
             {i18n.str`Confirm withdrawal`}
           </ButtonSuccess>
-        }
-        {terms.status === 'notfound' &&
+        )}
+        {terms.status === "notfound" && (
           <ButtonWarning
             upperCased
             disabled={!exchangeBaseUrl}
@@ -231,60 +297,88 @@ export function View({ details, withdrawalFee, 
exchangeBaseUrl, knownExchanges,
           >
             {i18n.str`Withdraw anyway`}
           </ButtonWarning>
-        }
+        )}
       </section>
     </WalletAction>
-  )
+  );
 }
 
-export function WithdrawPageWithParsedURI({ uri, uriInfo }: { uri: string, 
uriInfo: WithdrawUriInfoResponse }) {
-  const [customExchange, setCustomExchange] = useState<string | 
undefined>(undefined)
-  const [errorAccepting, setErrorAccepting] = useState<string | 
undefined>(undefined)
-
-  const [reviewing, setReviewing] = useState<boolean>(false)
-  const [reviewed, setReviewed] = useState<boolean>(false)
-  const [confirmed, setConfirmed] = useState<boolean>(false)
-
-  const knownExchangesHook = useAsyncAsHook(() => listExchanges())
-
-  const knownExchanges = !knownExchangesHook || knownExchangesHook.hasError ? 
[] : knownExchangesHook.response.exchanges
-  const withdrawAmount = Amounts.parseOrThrow(uriInfo.amount)
-  const thisCurrencyExchanges = knownExchanges.filter(ex => ex.currency === 
withdrawAmount.currency)
-
-  const exchange = customExchange || uriInfo.defaultExchangeBaseUrl || 
thisCurrencyExchanges[0]?.exchangeBaseUrl
+export function WithdrawPageWithParsedURI({
+  uri,
+  uriInfo,
+}: {
+  uri: string;
+  uriInfo: WithdrawUriInfoResponse;
+}) {
+  const [customExchange, setCustomExchange] = useState<string | undefined>(
+    undefined,
+  );
+  const [errorAccepting, setErrorAccepting] = useState<string | undefined>(
+    undefined,
+  );
+
+  const [reviewing, setReviewing] = useState<boolean>(false);
+  const [reviewed, setReviewed] = useState<boolean>(false);
+  const [confirmed, setConfirmed] = useState<boolean>(false);
+
+  const knownExchangesHook = useAsyncAsHook(() => listExchanges());
+
+  const knownExchanges =
+    !knownExchangesHook || knownExchangesHook.hasError
+      ? []
+      : knownExchangesHook.response.exchanges;
+  const withdrawAmount = Amounts.parseOrThrow(uriInfo.amount);
+  const thisCurrencyExchanges = knownExchanges.filter(
+    (ex) => ex.currency === withdrawAmount.currency,
+  );
+
+  const exchange =
+    customExchange ||
+    uriInfo.defaultExchangeBaseUrl ||
+    thisCurrencyExchanges[0]?.exchangeBaseUrl;
   const detailsHook = useAsyncAsHook(async () => {
-    if (!exchange) throw Error('no default exchange')
-    const tos = await getExchangeTos(exchange, ['text/xml'])
+    if (!exchange) throw Error("no default exchange");
+    const tos = await getExchangeTos(exchange, ["text/xml"]);
     const info = await getExchangeWithdrawalInfo({
       exchangeBaseUrl: exchange,
       amount: withdrawAmount,
-      tosAcceptedFormat: ['text/xml']
-    })
-    return { tos, info }
-  })
+      tosAcceptedFormat: ["text/xml"],
+    });
+    return { tos, info };
+  });
 
   if (!detailsHook) {
-    return <span><i18n.Translate>Getting withdrawal 
details.</i18n.Translate></span>;
+    return (
+      <span>
+        <i18n.Translate>Getting withdrawal details.</i18n.Translate>
+      </span>
+    );
   }
   if (detailsHook.hasError) {
-    return <span><i18n.Translate>Problems getting details: 
{detailsHook.message}</i18n.Translate></span>;
+    return (
+      <span>
+        <i18n.Translate>
+          Problems getting details: {detailsHook.message}
+        </i18n.Translate>
+      </span>
+    );
   }
 
-  const details = detailsHook.response
+  const details = detailsHook.response;
 
   const onAccept = async (): Promise<void> => {
     try {
-      await setExchangeTosAccepted(exchange, details.tos.currentEtag)
-      setReviewed(true)
+      await setExchangeTosAccepted(exchange, details.tos.currentEtag);
+      setReviewed(true);
     } catch (e) {
       if (e instanceof Error) {
-        setErrorAccepting(e.message)
+        setErrorAccepting(e.message);
       }
     }
-  }
+  };
 
   const onWithdraw = async (): Promise<void> => {
-    setConfirmed(true)
+    setConfirmed(true);
     console.log("accepting exchange", exchange);
     try {
       const res = await acceptWithdrawal(uri, exchange);
@@ -293,91 +387,121 @@ export function WithdrawPageWithParsedURI({ uri, uriInfo 
}: { uri: string, uriIn
         document.location.href = res.confirmTransferUrl;
       }
     } catch (e) {
-      setConfirmed(false)
+      setConfirmed(false);
     }
   };
 
-  const termsContent: TermsDocument | undefined = 
parseTermsOfServiceContent(details.tos.contentType, details.tos.content);
-
-  const status: TermsStatus = !termsContent ? 'notfound' : (
-    !details.tos.acceptedEtag ? 'new' : (
-      details.tos.acceptedEtag !== details.tos.currentEtag ? 'changed' : 
'accepted'
-    ))
-
-
-  return <View onWithdraw={onWithdraw}
-    details={details.tos} amount={withdrawAmount}
-    exchangeBaseUrl={exchange}
-    withdrawalFee={details.info.withdrawFee} //FIXME
-    terms={{
-      status, value: termsContent
-    }}
-    onSwitchExchange={setCustomExchange}
-    knownExchanges={knownExchanges}
-    confirmed={confirmed}
-    reviewed={reviewed} onAccept={onAccept}
-    reviewing={reviewing} onReview={setReviewing}
-  />
+  const termsContent: TermsDocument | undefined = parseTermsOfServiceContent(
+    details.tos.contentType,
+    details.tos.content,
+  );
+
+  const status: TermsStatus = !termsContent
+    ? "notfound"
+    : !details.tos.acceptedEtag
+    ? "new"
+    : details.tos.acceptedEtag !== details.tos.currentEtag
+    ? "changed"
+    : "accepted";
+
+  return (
+    <View
+      onWithdraw={onWithdraw}
+      details={details.tos}
+      amount={withdrawAmount}
+      exchangeBaseUrl={exchange}
+      withdrawalFee={details.info.withdrawFee} //FIXME
+      terms={{
+        status,
+        value: termsContent,
+      }}
+      onSwitchExchange={setCustomExchange}
+      knownExchanges={knownExchanges}
+      confirmed={confirmed}
+      reviewed={reviewed}
+      onAccept={onAccept}
+      reviewing={reviewing}
+      onReview={setReviewing}
+    />
+  );
 }
-export function WithdrawPage({ talerWithdrawUri }: Props): JSX.Element {
-  const uriInfoHook = useAsyncAsHook(() => !talerWithdrawUri ? 
Promise.reject(undefined) :
-    getWithdrawalDetailsForUri({ talerWithdrawUri })
-  )
+export function WithdrawPage({ talerWithdrawUri }: Props): VNode {
+  const uriInfoHook = useAsyncAsHook(() =>
+    !talerWithdrawUri
+      ? Promise.reject(undefined)
+      : getWithdrawalDetailsForUri({ talerWithdrawUri }),
+  );
 
   if (!talerWithdrawUri) {
-    return <span><i18n.Translate>missing withdraw uri</i18n.Translate></span>;
+    return (
+      <span>
+        <i18n.Translate>missing withdraw uri</i18n.Translate>
+      </span>
+    );
   }
   if (!uriInfoHook) {
-    return <span><i18n.Translate>Loading...</i18n.Translate></span>;
+    return (
+      <span>
+        <i18n.Translate>Loading...</i18n.Translate>
+      </span>
+    );
   }
   if (uriInfoHook.hasError) {
-    return <span><i18n.Translate>This URI is not valid anymore: 
{uriInfoHook.message}</i18n.Translate></span>;
+    return (
+      <span>
+        <i18n.Translate>
+          This URI is not valid anymore: {uriInfoHook.message}
+        </i18n.Translate>
+      </span>
+    );
   }
-  return <WithdrawPageWithParsedURI uri={talerWithdrawUri} 
uriInfo={uriInfoHook.response} />
+  return (
+    <WithdrawPageWithParsedURI
+      uri={talerWithdrawUri}
+      uriInfo={uriInfoHook.response}
+    />
+  );
 }
 
-function parseTermsOfServiceContent(type: string, text: string): TermsDocument 
| undefined {
-  if (type === 'text/xml') {
+function parseTermsOfServiceContent(
+  type: string,
+  text: string,
+): TermsDocument | undefined {
+  if (type === "text/xml") {
     try {
-      const document = new DOMParser().parseFromString(text, "text/xml")
-      return { type: 'xml', document }
+      const document = new DOMParser().parseFromString(text, "text/xml");
+      return { type: "xml", document };
     } catch (e) {
-      console.log(e)
-      debugger;
+      console.log(e);
     }
-  } else if (type === 'text/html') {
+  } else if (type === "text/html") {
     try {
-      const href = new URL(text)
-      return { type: 'html', href }
+      const href = new URL(text);
+      return { type: "html", href };
     } catch (e) {
-      console.log(e)
-      debugger;
+      console.log(e);
     }
-  } else if (type === 'text/json') {
+  } else if (type === "text/json") {
     try {
-      const data = JSON.parse(text)
-      return { type: 'json', data }
+      const data = JSON.parse(text);
+      return { type: "json", data };
     } catch (e) {
-      console.log(e)
-      debugger;
+      console.log(e);
     }
-  } else if (type === 'text/pdf') {
+  } else if (type === "text/pdf") {
     try {
-      const location = new URL(text)
-      return { type: 'pdf', location }
+      const location = new URL(text);
+      return { type: "pdf", location };
     } catch (e) {
-      console.log(e)
-      debugger;
+      console.log(e);
     }
-  } else if (type === 'text/plain') {
+  } else if (type === "text/plain") {
     try {
-      const content = text
-      return { type: 'plain', content }
+      const content = text;
+      return { type: "plain", content };
     } catch (e) {
-      console.log(e)
-      debugger;
+      console.log(e);
     }
   }
-  return undefined
+  return undefined;
 }
-
diff --git a/packages/taler-wallet-webextension/src/cta/payback.tsx 
b/packages/taler-wallet-webextension/src/cta/payback.tsx
index 1e27fd91..60cb8c51 100644
--- a/packages/taler-wallet-webextension/src/cta/payback.tsx
+++ b/packages/taler-wallet-webextension/src/cta/payback.tsx
@@ -15,7 +15,7 @@
  */
 
 import { JSX } from "preact/jsx-runtime";
-import { h } from 'preact';
+import { h } from "preact";
 
 /**
  * View and edit auditors.
diff --git a/packages/taler-wallet-webextension/src/cta/reset-required.tsx 
b/packages/taler-wallet-webextension/src/cta/reset-required.tsx
index e66c0db5..3949318c 100644
--- a/packages/taler-wallet-webextension/src/cta/reset-required.tsx
+++ b/packages/taler-wallet-webextension/src/cta/reset-required.tsx
@@ -63,7 +63,7 @@ class ResetNotification extends Component<any, State> {
             type="checkbox"
             checked={this.state.checked}
             onChange={() => {
-              this.setState(prev => ({ checked: prev.checked }))
+              this.setState((prev) => ({ checked: prev.checked }));
             }}
           />{" "}
           <label htmlFor="check">
diff --git a/packages/taler-wallet-webextension/src/cta/return-coins.tsx 
b/packages/taler-wallet-webextension/src/cta/return-coins.tsx
index 43d73b5f..548202ca 100644
--- a/packages/taler-wallet-webextension/src/cta/return-coins.tsx
+++ b/packages/taler-wallet-webextension/src/cta/return-coins.tsx
@@ -15,7 +15,7 @@
  */
 
 import { JSX } from "preact/jsx-runtime";
-import { h } from 'preact';
+import { h } from "preact";
 /**
  * Return coins to own bank account.
  *
diff --git a/packages/taler-wallet-webextension/src/custom.d.ts 
b/packages/taler-wallet-webextension/src/custom.d.ts
index 1981067d..521b824c 100644
--- a/packages/taler-wallet-webextension/src/custom.d.ts
+++ b/packages/taler-wallet-webextension/src/custom.d.ts
@@ -21,7 +21,7 @@ declare module "*.png" {
   const content: any;
   export default content;
 }
-declare module '*.svg' {
+declare module "*.svg" {
   const content: any;
   export default content;
 }
diff --git a/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts 
b/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts
index 2131d45c..aa6695c3 100644
--- a/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts
@@ -29,7 +29,7 @@ interface HookError {
 
 export type HookResponse<T> = HookOk<T> | HookError | undefined;
 
-export function useAsyncAsHook<T> (fn: (() => Promise<T>)): HookResponse<T> {
+export function useAsyncAsHook<T>(fn: () => Promise<T>): HookResponse<T> {
   const [result, setHookResponse] = useState<HookResponse<T>>(undefined);
   useEffect(() => {
     async function doAsync() {
@@ -42,7 +42,7 @@ export function useAsyncAsHook<T> (fn: (() => Promise<T>)): 
HookResponse<T> {
         }
       }
     }
-    doAsync()
+    doAsync();
   }, []);
   return result;
 }
diff --git 
a/packages/taler-wallet-webextension/src/hooks/useBackupDeviceName.ts 
b/packages/taler-wallet-webextension/src/hooks/useBackupDeviceName.ts
index f3b1b3b5..1aa711a9 100644
--- a/packages/taler-wallet-webextension/src/hooks/useBackupDeviceName.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useBackupDeviceName.ts
@@ -17,34 +17,31 @@
 import { useEffect, useState } from "preact/hooks";
 import * as wxApi from "../wxApi";
 
-
 export interface BackupDeviceName {
   name: string;
-  update: (s:string) => Promise<void>
+  update: (s: string) => Promise<void>;
 }
 
-
 export function useBackupDeviceName(): BackupDeviceName {
   const [status, setStatus] = useState<BackupDeviceName>({
-    name: '',
-    update: () => Promise.resolve()
-  })
+    name: "",
+    update: () => Promise.resolve(),
+  });
 
   useEffect(() => {
     async function run() {
       //create a first list of backup info by currency
-      const status = await wxApi.getBackupInfo()
+      const status = await wxApi.getBackupInfo();
 
       async function update(newName: string) {
-        await wxApi.setWalletDeviceId(newName)
-        setStatus(old => ({ ...old, name: newName }))  
+        await wxApi.setWalletDeviceId(newName);
+        setStatus((old) => ({ ...old, name: newName }));
       }
 
-      setStatus({ name: status.deviceId, update })
+      setStatus({ name: status.deviceId, update });
     }
-    run()
-  }, [])
+    run();
+  }, []);
 
-  return status
+  return status;
 }
-
diff --git a/packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts 
b/packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts
index c46ab6a5..8a8fd6f2 100644
--- a/packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts
@@ -14,11 +14,15 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { ProviderInfo, ProviderPaymentPaid, ProviderPaymentStatus, 
ProviderPaymentType } from "@gnu-taler/taler-wallet-core";
+import {
+  ProviderInfo,
+  ProviderPaymentPaid,
+  ProviderPaymentStatus,
+  ProviderPaymentType,
+} from "@gnu-taler/taler-wallet-core";
 import { useEffect, useState } from "preact/hooks";
 import * as wxApi from "../wxApi";
 
-
 export interface BackupStatus {
   deviceName: string;
   providers: ProviderInfo[];
@@ -32,40 +36,46 @@ function getStatusTypeOrder(t: ProviderPaymentStatus) {
     ProviderPaymentType.Unpaid,
     ProviderPaymentType.Paid,
     ProviderPaymentType.Pending,
-  ].indexOf(t.type)
+  ].indexOf(t.type);
 }
 
 function getStatusPaidOrder(a: ProviderPaymentPaid, b: ProviderPaymentPaid) {
-  return a.paidUntil.t_ms === 'never' ? -1 :
-    b.paidUntil.t_ms === 'never' ? 1 :
-      a.paidUntil.t_ms - b.paidUntil.t_ms
+  return a.paidUntil.t_ms === "never"
+    ? -1
+    : b.paidUntil.t_ms === "never"
+    ? 1
+    : a.paidUntil.t_ms - b.paidUntil.t_ms;
 }
 
 export function useBackupStatus(): BackupStatus | undefined {
-  const [status, setStatus] = useState<BackupStatus | undefined>(undefined)
+  const [status, setStatus] = useState<BackupStatus | undefined>(undefined);
 
   useEffect(() => {
     async function run() {
       //create a first list of backup info by currency
-      const status = await wxApi.getBackupInfo()
+      const status = await wxApi.getBackupInfo();
 
       const providers = status.providers.sort((a, b) => {
-        if (a.paymentStatus.type === ProviderPaymentType.Paid && 
b.paymentStatus.type === ProviderPaymentType.Paid) {
-          return getStatusPaidOrder(a.paymentStatus, b.paymentStatus)
+        if (
+          a.paymentStatus.type === ProviderPaymentType.Paid &&
+          b.paymentStatus.type === ProviderPaymentType.Paid
+        ) {
+          return getStatusPaidOrder(a.paymentStatus, b.paymentStatus);
         }
-        return getStatusTypeOrder(a.paymentStatus) - 
getStatusTypeOrder(b.paymentStatus)
-      })
+        return (
+          getStatusTypeOrder(a.paymentStatus) -
+          getStatusTypeOrder(b.paymentStatus)
+        );
+      });
 
       async function sync() {
-        await wxApi.syncAllProviders()
+        await wxApi.syncAllProviders();
       }
-      
-      setStatus({ deviceName: status.deviceId, providers, sync })
+
+      setStatus({ deviceName: status.deviceId, providers, sync });
     }
-    run()
-  }, [])
+    run();
+  }, []);
 
-  return status
+  return status;
 }
-
-
diff --git a/packages/taler-wallet-webextension/src/hooks/useBalances.ts 
b/packages/taler-wallet-webextension/src/hooks/useBalances.ts
index 37424fb0..403ce7b8 100644
--- a/packages/taler-wallet-webextension/src/hooks/useBalances.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useBalances.ts
@@ -18,7 +18,6 @@ import { BalancesResponse } from "@gnu-taler/taler-util";
 import { useEffect, useState } from "preact/hooks";
 import * as wxApi from "../wxApi";
 
-
 interface BalancesHookOk {
   hasError: false;
   response: BalancesResponse;
@@ -46,7 +45,7 @@ export function useBalances(): BalancesHook {
         }
       }
     }
-    checkBalance()
+    checkBalance();
     return wxApi.onUpdateNotification(checkBalance);
   }, []);
 
diff --git a/packages/taler-wallet-webextension/src/hooks/useDiagnostics.ts 
b/packages/taler-wallet-webextension/src/hooks/useDiagnostics.ts
index 888d4d5f..48aff260 100644
--- a/packages/taler-wallet-webextension/src/hooks/useDiagnostics.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useDiagnostics.ts
@@ -21,7 +21,7 @@ import * as wxApi from "../wxApi";
 export function useDiagnostics(): [WalletDiagnostics | undefined, boolean] {
   const [timedOut, setTimedOut] = useState(false);
   const [diagnostics, setDiagnostics] = useState<WalletDiagnostics | 
undefined>(
-    undefined
+    undefined,
   );
 
   useEffect(() => {
@@ -41,5 +41,5 @@ export function useDiagnostics(): [WalletDiagnostics | 
undefined, boolean] {
     console.log("fetching diagnostics");
     doFetch();
   }, []);
-  return [diagnostics, timedOut]
-}
\ No newline at end of file
+  return [diagnostics, timedOut];
+}
diff --git 
a/packages/taler-wallet-webextension/src/hooks/useExtendedPermissions.ts 
b/packages/taler-wallet-webextension/src/hooks/useExtendedPermissions.ts
index a9242576..aaab0aa4 100644
--- a/packages/taler-wallet-webextension/src/hooks/useExtendedPermissions.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useExtendedPermissions.ts
@@ -19,13 +19,12 @@ import * as wxApi from "../wxApi";
 import { getPermissionsApi } from "../compat";
 import { extendedPermissions } from "../permissions";
 
-
 export function useExtendedPermissions(): [boolean, () => void] {
   const [enabled, setEnabled] = useState(false);
 
   const toggle = () => {
-    setEnabled(v => !v);
-    handleExtendedPerm(enabled).then(result => {
+    setEnabled((v) => !v);
+    handleExtendedPerm(enabled).then((result) => {
       setEnabled(result);
     });
   };
@@ -65,5 +64,5 @@ async function handleExtendedPerm(isEnabled: boolean): 
Promise<boolean> {
     nextVal = res.newValue;
   }
   console.log("new permissions applied:", nextVal ?? false);
-  return nextVal ?? false
-}
\ No newline at end of file
+  return nextVal ?? false;
+}
diff --git a/packages/taler-wallet-webextension/src/hooks/useLang.ts 
b/packages/taler-wallet-webextension/src/hooks/useLang.ts
index 70b9614f..cc4ff3fc 100644
--- a/packages/taler-wallet-webextension/src/hooks/useLang.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useLang.ts
@@ -14,10 +14,13 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { useNotNullLocalStorage } from './useLocalStorage';
+import { useNotNullLocalStorage } from "./useLocalStorage";
 
-export function useLang(initial?: string): [string, (s:string) => void] {
-  const browserLang: string | undefined = typeof window !== "undefined" ? 
navigator.language || (navigator as any).userLanguage : undefined;
-  const defaultLang = (browserLang || initial || 'en').substring(0, 2)
-  return useNotNullLocalStorage('lang-preference', defaultLang)
+export function useLang(initial?: string): [string, (s: string) => void] {
+  const browserLang: string | undefined =
+    typeof window !== "undefined"
+      ? navigator.language || (navigator as any).userLanguage
+      : undefined;
+  const defaultLang = (browserLang || initial || "en").substring(0, 2);
+  return useNotNullLocalStorage("lang-preference", defaultLang);
 }
diff --git a/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts 
b/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts
index 78a8b65d..3883aff0 100644
--- a/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts
@@ -15,38 +15,52 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
 import { StateUpdater, useState } from "preact/hooks";
 
-export function useLocalStorage(key: string, initialValue?: string): [string | 
undefined, StateUpdater<string | undefined>] {
-  const [storedValue, setStoredValue] = useState<string | undefined>((): 
string | undefined => {
-    return typeof window !== "undefined" ? window.localStorage.getItem(key) || 
initialValue : initialValue;
+export function useLocalStorage(
+  key: string,
+  initialValue?: string,
+): [string | undefined, StateUpdater<string | undefined>] {
+  const [storedValue, setStoredValue] = useState<string | undefined>(():
+    | string
+    | undefined => {
+    return typeof window !== "undefined"
+      ? window.localStorage.getItem(key) || initialValue
+      : initialValue;
   });
 
-  const setValue = (value?: string | ((val?: string) => string | undefined)) 
=> {
-    setStoredValue(p => {
-      const toStore = value instanceof Function ? value(p) : value
+  const setValue = (
+    value?: string | ((val?: string) => string | undefined),
+  ) => {
+    setStoredValue((p) => {
+      const toStore = value instanceof Function ? value(p) : value;
       if (typeof window !== "undefined") {
         if (!toStore) {
-          window.localStorage.removeItem(key)
+          window.localStorage.removeItem(key);
         } else {
           window.localStorage.setItem(key, toStore);
         }
       }
-      return toStore
-    })
+      return toStore;
+    });
   };
 
   return [storedValue, setValue];
 }
 
 //TODO: merge with the above function
-export function useNotNullLocalStorage(key: string, initialValue: string): 
[string, StateUpdater<string>] {
+export function useNotNullLocalStorage(
+  key: string,
+  initialValue: string,
+): [string, StateUpdater<string>] {
   const [storedValue, setStoredValue] = useState<string>((): string => {
-    return typeof window !== "undefined" ? window.localStorage.getItem(key) || 
initialValue : initialValue;
+    return typeof window !== "undefined"
+      ? window.localStorage.getItem(key) || initialValue
+      : initialValue;
   });
 
   const setValue = (value: string | ((val: string) => string)) => {
@@ -54,7 +68,7 @@ export function useNotNullLocalStorage(key: string, 
initialValue: string): [stri
     setStoredValue(valueToStore);
     if (typeof window !== "undefined") {
       if (!valueToStore) {
-        window.localStorage.removeItem(key)
+        window.localStorage.removeItem(key);
       } else {
         window.localStorage.setItem(key, valueToStore);
       }
diff --git a/packages/taler-wallet-webextension/src/hooks/useProviderStatus.ts 
b/packages/taler-wallet-webextension/src/hooks/useProviderStatus.ts
index 6520848a..ea167463 100644
--- a/packages/taler-wallet-webextension/src/hooks/useProviderStatus.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useProviderStatus.ts
@@ -32,7 +32,9 @@ export function useProviderStatus(url: string): 
ProviderStatus | undefined {
       //create a first list of backup info by currency
       const status = await wxApi.getBackupInfo();
 
-      const providers = status.providers.filter(p => p.syncProviderBaseUrl === 
url);
+      const providers = status.providers.filter(
+        (p) => p.syncProviderBaseUrl === url,
+      );
       const info = providers.length ? providers[0] : undefined;
 
       async function sync() {
diff --git a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts 
b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts
index ff9cc029..96a27840 100644
--- a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts
@@ -17,15 +17,18 @@
 import { classifyTalerUri, TalerUriType } from "@gnu-taler/taler-util";
 import { useEffect, useState } from "preact/hooks";
 
-export function useTalerActionURL(): [string | undefined, (s: boolean) => 
void] {
+export function useTalerActionURL(): [
+  string | undefined,
+  (s: boolean) => void,
+] {
   const [talerActionUrl, setTalerActionUrl] = useState<string | undefined>(
-    undefined
+    undefined,
   );
   const [dismissed, setDismissed] = useState(false);
   useEffect(() => {
     async function check(): Promise<void> {
       const talerUri = await findTalerUriInActiveTab();
-      setTalerActionUrl(talerUri)
+      setTalerActionUrl(talerUri);
     }
     check();
   }, []);
diff --git a/packages/taler-wallet-webextension/src/i18n/strings.ts 
b/packages/taler-wallet-webextension/src/i18n/strings.ts
index 5b125783..0fefb0f7 100644
--- a/packages/taler-wallet-webextension/src/i18n/strings.ts
+++ b/packages/taler-wallet-webextension/src/i18n/strings.ts
@@ -193,7 +193,7 @@ strings["es"] = {
       "Order redirected": [""],
       "Payment aborted": [""],
       "Payment Sent": [""],
-      "Backup": ["Resguardo"],
+      Backup: ["Resguardo"],
       "Order accepted": [""],
       "Reserve balance updated": [""],
       "Payment refund": [""],
diff --git a/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx 
b/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx
index d256f6d9..232b0da7 100644
--- a/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx
@@ -15,179 +15,184 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { ProviderPaymentType } from '@gnu-taler/taler-wallet-core';
-import { addDays } from 'date-fns';
-import { BackupView as TestedComponent } from './BackupPage';
-import { createExample } from '../test-utils';
+import { ProviderPaymentType } from "@gnu-taler/taler-wallet-core";
+import { addDays } from "date-fns";
+import { BackupView as TestedComponent } from "./BackupPage";
+import { createExample } from "../test-utils";
 
 export default {
-  title: 'popup/backup/list',
+  title: "popup/backup/list",
   component: TestedComponent,
   argTypes: {
-    onRetry: { action: 'onRetry' },
-    onDelete: { action: 'onDelete' },
-    onBack: { action: 'onBack' },
-  }
+    onRetry: { action: "onRetry" },
+    onDelete: { action: "onDelete" },
+    onBack: { action: "onBack" },
+  },
 };
 
-
 export const LotOfProviders = createExample(TestedComponent, {
-  providers: [{
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
-    },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
-    ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
-    },
-    "terms": {
-      "annualFee": "ARS:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
+  providers: [
+    {
+      active: true,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.taler:9967/";,
+      lastSuccessfulBackupTimestamp: {
+        t_ms: 1625063925078,
+      },
+      paymentProposalIds: [
+        "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
+      ],
+      paymentStatus: {
+        type: ProviderPaymentType.Paid,
+        paidUntil: {
+          t_ms: 1656599921000,
+        },
+      },
+      terms: {
+        annualFee: "ARS:1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
-    ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": addDays(new Date(), 13).getTime()
-      }
+    {
+      active: true,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.taler:9967/";,
+      lastSuccessfulBackupTimestamp: {
+        t_ms: 1625063925078,
+      },
+      paymentProposalIds: [
+        "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
+      ],
+      paymentStatus: {
+        type: ProviderPaymentType.Paid,
+        paidUntil: {
+          t_ms: addDays(new Date(), 13).getTime(),
+        },
+      },
+      terms: {
+        annualFee: "ARS:1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "ARS:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Pending,
+    {
+      active: false,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+      paymentProposalIds: [],
+      paymentStatus: {
+        type: ProviderPaymentType.Pending,
+      },
+      terms: {
+        annualFee: "KUDOS:0.1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "KUDOS:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.InsufficientBalance,
+    {
+      active: false,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+      paymentProposalIds: [],
+      paymentStatus: {
+        type: ProviderPaymentType.InsufficientBalance,
+      },
+      terms: {
+        annualFee: "KUDOS:0.1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "KUDOS:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.TermsChanged,
-      newTerms: {
-        annualFee: 'USD:2',
-        storageLimitInMegabytes: 8,
-        supportedProtocolVersion: '2',
-      },
-      oldTerms: {
-        annualFee: 'USD:1',
+    {
+      active: false,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+      paymentProposalIds: [],
+      paymentStatus: {
+        type: ProviderPaymentType.TermsChanged,
+        newTerms: {
+          annualFee: "USD:2",
+          storageLimitInMegabytes: 8,
+          supportedProtocolVersion: "2",
+        },
+        oldTerms: {
+          annualFee: "USD:1",
+          storageLimitInMegabytes: 16,
+          supportedProtocolVersion: "1",
+        },
+        paidUntil: {
+          t_ms: "never",
+        },
+      },
+      terms: {
+        annualFee: "KUDOS:0.1",
         storageLimitInMegabytes: 16,
-        supportedProtocolVersion: '1',
-
+        supportedProtocolVersion: "0.0",
       },
-      paidUntil: {
-        t_ms: 'never'
-      }
     },
-    "terms": {
-      "annualFee": "KUDOS:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Unpaid,
+    {
+      active: false,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+      paymentProposalIds: [],
+      paymentStatus: {
+        type: ProviderPaymentType.Unpaid,
+      },
+      terms: {
+        annualFee: "KUDOS:0.1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "KUDOS:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Unpaid,
+    {
+      active: false,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+      paymentProposalIds: [],
+      paymentStatus: {
+        type: ProviderPaymentType.Unpaid,
+      },
+      terms: {
+        annualFee: "KUDOS:0.1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "KUDOS:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }]
+  ],
 });
 
-
 export const OneProvider = createExample(TestedComponent, {
-  providers: [{
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
-    },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
-    ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
+  providers: [
+    {
+      active: true,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.taler:9967/";,
+      lastSuccessfulBackupTimestamp: {
+        t_ms: 1625063925078,
+      },
+      paymentProposalIds: [
+        "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
+      ],
+      paymentStatus: {
+        type: ProviderPaymentType.Paid,
+        paidUntil: {
+          t_ms: 1656599921000,
+        },
+      },
+      terms: {
+        annualFee: "ARS:1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "ARS:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }]
+  ],
 });
 
-
 export const Empty = createExample(TestedComponent, {
-  providers: []
+  providers: [],
 });
-
diff --git a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx 
b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx
index dcc5e531..894c8a79 100644
--- a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx
+++ b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx
@@ -14,15 +14,28 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 
-
 import { i18n, Timestamp } from "@gnu-taler/taler-util";
-import { ProviderInfo, ProviderPaymentStatus } from 
"@gnu-taler/taler-wallet-core";
-import { differenceInMonths, formatDuration, intervalToDuration } from 
"date-fns";
+import {
+  ProviderInfo,
+  ProviderPaymentStatus,
+} from "@gnu-taler/taler-wallet-core";
+import {
+  differenceInMonths,
+  formatDuration,
+  intervalToDuration,
+} from "date-fns";
 import { Fragment, JSX, VNode, h } from "preact";
 import {
-  BoldLight, ButtonPrimary, ButtonSuccess, Centered,
-  CenteredText, CenteredBoldText, PopupBox, RowBorderGray,
-  SmallText, SmallLightText
+  BoldLight,
+  ButtonPrimary,
+  ButtonSuccess,
+  Centered,
+  CenteredText,
+  CenteredBoldText,
+  PopupBox,
+  RowBorderGray,
+  SmallText,
+  SmallLightText,
 } from "../components/styled";
 import { useBackupStatus } from "../hooks/useBackupStatus";
 import { Pages } from "../NavigationBar";
@@ -32,49 +45,68 @@ interface Props {
 }
 
 export function BackupPage({ onAddProvider }: Props): VNode {
-  const status = useBackupStatus()
+  const status = useBackupStatus();
   if (!status) {
-    return <div>Loading...</div>
+    return <div>Loading...</div>;
   }
-  return <BackupView providers={status.providers} 
onAddProvider={onAddProvider} onSyncAll={status.sync} />;
+  return (
+    <BackupView
+      providers={status.providers}
+      onAddProvider={onAddProvider}
+      onSyncAll={status.sync}
+    />
+  );
 }
 
 export interface ViewProps {
-  providers: ProviderInfo[],
+  providers: ProviderInfo[];
   onAddProvider: () => void;
   onSyncAll: () => Promise<void>;
 }
 
-export function BackupView({ providers, onAddProvider, onSyncAll }: 
ViewProps): VNode {
+export function BackupView({
+  providers,
+  onAddProvider,
+  onSyncAll,
+}: ViewProps): VNode {
   return (
     <PopupBox>
       <section>
-        {providers.map((provider) => <BackupLayout
-          status={provider.paymentStatus}
-          timestamp={provider.lastSuccessfulBackupTimestamp}
-          id={provider.syncProviderBaseUrl}
-          active={provider.active}
-          title={provider.name}
-        />
+        {providers.map((provider) => (
+          <BackupLayout
+            status={provider.paymentStatus}
+            timestamp={provider.lastSuccessfulBackupTimestamp}
+            id={provider.syncProviderBaseUrl}
+            active={provider.active}
+            title={provider.name}
+          />
+        ))}
+        {!providers.length && (
+          <Centered style={{ marginTop: 100 }}>
+            <BoldLight>No backup providers configured</BoldLight>
+            <ButtonSuccess onClick={onAddProvider}>
+              <i18n.Translate>Add provider</i18n.Translate>
+            </ButtonSuccess>
+          </Centered>
         )}
-        {!providers.length && <Centered style={{marginTop: 100}}>
-          <BoldLight>No backup providers configured</BoldLight>
-          <ButtonSuccess onClick={onAddProvider}><i18n.Translate>Add 
provider</i18n.Translate></ButtonSuccess>
-        </Centered>}
       </section>
-      {!!providers.length && <footer>
-        <div />
-        <div>
-          <ButtonPrimary onClick={onSyncAll}>{
-            providers.length > 1 ?
-              <i18n.Translate>Sync all backups</i18n.Translate> :
-              <i18n.Translate>Sync now</i18n.Translate>
-          }</ButtonPrimary>
-          <ButtonSuccess onClick={onAddProvider}>Add provider</ButtonSuccess>
-        </div>
-      </footer>}
+      {!!providers.length && (
+        <footer>
+          <div />
+          <div>
+            <ButtonPrimary onClick={onSyncAll}>
+              {providers.length > 1 ? (
+                <i18n.Translate>Sync all backups</i18n.Translate>
+              ) : (
+                <i18n.Translate>Sync now</i18n.Translate>
+              )}
+            </ButtonPrimary>
+            <ButtonSuccess onClick={onAddProvider}>Add provider</ButtonSuccess>
+          </div>
+        </footer>
+      )}
     </PopupBox>
-  )
+  );
 }
 
 interface TransactionLayoutProps {
@@ -92,55 +124,73 @@ function BackupLayout(props: TransactionLayoutProps): 
JSX.Element {
     timeStyle: "short",
   } as any);
 
-
   return (
     <RowBorderGray>
       <div style={{ color: !props.active ? "grey" : undefined }}>
-        <a href={Pages.provider_detail.replace(':pid', 
encodeURIComponent(props.id))}><span>{props.title}</span></a>
-
-        {dateStr && <SmallText style={{marginTop: 5}}>Last synced: 
{dateStr}</SmallText>}
-        {!dateStr && <SmallLightText style={{marginTop: 5}}>Not 
synced</SmallLightText>}
+        <a
+          href={Pages.provider_detail.replace(
+            ":pid",
+            encodeURIComponent(props.id),
+          )}
+        >
+          <span>{props.title}</span>
+        </a>
+
+        {dateStr && (
+          <SmallText style={{ marginTop: 5 }}>Last synced: 
{dateStr}</SmallText>
+        )}
+        {!dateStr && (
+          <SmallLightText style={{ marginTop: 5 }}>Not synced</SmallLightText>
+        )}
       </div>
       <div>
-        {props.status?.type === 'paid' ?
-          <ExpirationText until={props.status.paidUntil} /> :
+        {props.status?.type === "paid" ? (
+          <ExpirationText until={props.status.paidUntil} />
+        ) : (
           <div>{props.status.type}</div>
-        }
+        )}
       </div>
     </RowBorderGray>
   );
 }
 
 function ExpirationText({ until }: { until: Timestamp }) {
-  return <Fragment>
-    <CenteredText> Expires in </CenteredText>
-    <CenteredBoldText {...({ color: colorByTimeToExpire(until) })}> 
{daysUntil(until)} </CenteredBoldText>
-  </Fragment>
+  return (
+    <Fragment>
+      <CenteredText> Expires in </CenteredText>
+      <CenteredBoldText {...{ color: colorByTimeToExpire(until) }}>
+        {" "}
+        {daysUntil(until)}{" "}
+      </CenteredBoldText>
+    </Fragment>
+  );
 }
 
 function colorByTimeToExpire(d: Timestamp) {
-  if (d.t_ms === 'never') return 'rgb(28, 184, 65)'
-  const months = differenceInMonths(d.t_ms, new Date())
-  return months > 1 ? 'rgb(28, 184, 65)' : 'rgb(223, 117, 20)';
+  if (d.t_ms === "never") return "rgb(28, 184, 65)";
+  const months = differenceInMonths(d.t_ms, new Date());
+  return months > 1 ? "rgb(28, 184, 65)" : "rgb(223, 117, 20)";
 }
 
 function daysUntil(d: Timestamp) {
-  if (d.t_ms === 'never') return undefined
+  if (d.t_ms === "never") return undefined;
   const duration = intervalToDuration({
     start: d.t_ms,
     end: new Date(),
-  })
+  });
   const str = formatDuration(duration, {
-    delimiter: ', ',
+    delimiter: ", ",
     format: [
-      duration?.years ? 'years' : (
-        duration?.months ? 'months' : (
-          duration?.days ? 'days' : (
-            duration.hours ? 'hours' : 'minutes'
-          )
-        )
-      )
-    ]
-  })
-  return `${str}`
-}
\ No newline at end of file
+      duration?.years
+        ? "years"
+        : duration?.months
+        ? "months"
+        : duration?.days
+        ? "days"
+        : duration.hours
+        ? "hours"
+        : "minutes",
+    ],
+  });
+  return `${str}`;
+}
diff --git a/packages/taler-wallet-webextension/src/popup/Balance.stories.tsx 
b/packages/taler-wallet-webextension/src/popup/Balance.stories.tsx
index 382f9b54..80203f6d 100644
--- a/packages/taler-wallet-webextension/src/popup/Balance.stories.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Balance.stories.tsx
@@ -15,28 +15,25 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample, NullLink } from '../test-utils';
-import { BalanceView as TestedComponent } from './BalancePage';
+import { createExample, NullLink } from "../test-utils";
+import { BalanceView as TestedComponent } from "./BalancePage";
 
 export default {
-  title: 'popup/balance',
+  title: "popup/balance",
   component: TestedComponent,
-  argTypes: {
-  }
+  argTypes: {},
 };
 
-
-export const NotYetLoaded = createExample(TestedComponent, {
-});
+export const NotYetLoaded = createExample(TestedComponent, {});
 
 export const GotError = createExample(TestedComponent, {
   balance: {
     hasError: true,
-    message: 'Network error'
+    message: "Network error",
   },
   Linker: NullLink,
 });
@@ -45,7 +42,7 @@ export const EmptyBalance = createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: []
+      balances: [],
     },
   },
   Linker: NullLink,
@@ -55,13 +52,15 @@ export const SomeCoins = createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: [{
-        available: 'USD:10.5',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:0',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      }]
+      balances: [
+        {
+          available: "USD:10.5",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:0",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+      ],
     },
   },
   Linker: NullLink,
@@ -71,13 +70,15 @@ export const SomeCoinsAndIncomingMoney = 
createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: [{
-        available: 'USD:2.23',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:5.11',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      }]
+      balances: [
+        {
+          available: "USD:2.23",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:5.11",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+      ],
     },
   },
   Linker: NullLink,
@@ -87,13 +88,15 @@ export const SomeCoinsAndOutgoingMoney = 
createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: [{
-        available: 'USD:2.23',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:0',
-        pendingOutgoing: 'USD:5.11',
-        requiresUserInput: false
-      }]
+      balances: [
+        {
+          available: "USD:2.23",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:0",
+          pendingOutgoing: "USD:5.11",
+          requiresUserInput: false,
+        },
+      ],
     },
   },
   Linker: NullLink,
@@ -103,13 +106,15 @@ export const SomeCoinsAndMovingMoney = 
createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: [{
-        available: 'USD:2.23',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:2',
-        pendingOutgoing: 'USD:5.11',
-        requiresUserInput: false
-      }]
+      balances: [
+        {
+          available: "USD:2.23",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:2",
+          pendingOutgoing: "USD:5.11",
+          requiresUserInput: false,
+        },
+      ],
     },
   },
   Linker: NullLink,
@@ -119,19 +124,22 @@ export const SomeCoinsInTwoCurrencies = 
createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: [{
-        available: 'USD:2',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:5.1',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      },{
-        available: 'EUR:4',
-        hasPendingTransactions: false,
-        pendingIncoming: 'EUR:0',
-        pendingOutgoing: 'EUR:3.01',
-        requiresUserInput: false
-      }]
+      balances: [
+        {
+          available: "USD:2",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:5.1",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+        {
+          available: "EUR:4",
+          hasPendingTransactions: false,
+          pendingIncoming: "EUR:0",
+          pendingOutgoing: "EUR:3.01",
+          requiresUserInput: false,
+        },
+      ],
     },
   },
   Linker: NullLink,
@@ -141,78 +149,89 @@ export const SomeCoinsInTreeCurrencies = 
createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: [{
-        available: 'USD:1',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:0',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      },{
-        available: 'COL:2000',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:0',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      },{
-        available: 'EUR:4',
-        hasPendingTransactions: false,
-        pendingIncoming: 'EUR:15',
-        pendingOutgoing: 'EUR:0',
-        requiresUserInput: false
-      }]
+      balances: [
+        {
+          available: "USD:1",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:0",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+        {
+          available: "COL:2000",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:0",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+        {
+          available: "EUR:4",
+          hasPendingTransactions: false,
+          pendingIncoming: "EUR:15",
+          pendingOutgoing: "EUR:0",
+          requiresUserInput: false,
+        },
+      ],
     },
   },
   Linker: NullLink,
 });
 
-
 export const SomeCoinsInFiveCurrencies = createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: [{
-        available: 'USD:13451',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:0',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      },{
-        available: 'EUR:202.02',
-        hasPendingTransactions: false,
-        pendingIncoming: 'EUR:0',
-        pendingOutgoing: 'EUR:0',
-        requiresUserInput: false
-      },{
-        available: 'ARS:30',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:0',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      },{
-        available: 'JPY:51223233',
-        hasPendingTransactions: false,
-        pendingIncoming: 'EUR:0',
-        pendingOutgoing: 'EUR:0',
-        requiresUserInput: false
-      },{
-        available: 'JPY:51223233',
-        hasPendingTransactions: false,
-        pendingIncoming: 'EUR:0',
-        pendingOutgoing: 'EUR:0',
-        requiresUserInput: false
-      },{
-        available: 'DEMOKUDOS:6',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:0',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      },{
-        available: 'TESTKUDOS:6',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:5',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      }]
+      balances: [
+        {
+          available: "USD:13451",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:0",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+        {
+          available: "EUR:202.02",
+          hasPendingTransactions: false,
+          pendingIncoming: "EUR:0",
+          pendingOutgoing: "EUR:0",
+          requiresUserInput: false,
+        },
+        {
+          available: "ARS:30",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:0",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+        {
+          available: "JPY:51223233",
+          hasPendingTransactions: false,
+          pendingIncoming: "EUR:0",
+          pendingOutgoing: "EUR:0",
+          requiresUserInput: false,
+        },
+        {
+          available: "JPY:51223233",
+          hasPendingTransactions: false,
+          pendingIncoming: "EUR:0",
+          pendingOutgoing: "EUR:0",
+          requiresUserInput: false,
+        },
+        {
+          available: "DEMOKUDOS:6",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:0",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+        {
+          available: "TESTKUDOS:6",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:5",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+      ],
     },
   },
   Linker: NullLink,
diff --git a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx 
b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
index 8e5c5c42..2913f60e 100644
--- a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
+++ b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
@@ -15,20 +15,37 @@
  */
 
 import {
-  amountFractionalBase, Amounts,
-  Balance, BalancesResponse,
-  i18n
+  amountFractionalBase,
+  Amounts,
+  Balance,
+  BalancesResponse,
+  i18n,
 } from "@gnu-taler/taler-util";
 import { JSX, h, Fragment } from "preact";
 import { ErrorMessage } from "../components/ErrorMessage";
-import { PopupBox, Centered, ButtonPrimary, ErrorBox, Middle } from 
"../components/styled/index";
+import {
+  PopupBox,
+  Centered,
+  ButtonPrimary,
+  ErrorBox,
+  Middle,
+} from "../components/styled/index";
 import { BalancesHook, useBalances } from "../hooks/useBalances";
 import { PageLink, renderAmount } from "../renderHtml";
 
-
-export function BalancePage({ goToWalletManualWithdraw }: { 
goToWalletManualWithdraw: () => void }) {
-  const balance = useBalances()
-  return <BalanceView balance={balance} Linker={PageLink} 
goToWalletManualWithdraw={goToWalletManualWithdraw} />
+export function BalancePage({
+  goToWalletManualWithdraw,
+}: {
+  goToWalletManualWithdraw: () => void;
+}) {
+  const balance = useBalances();
+  return (
+    <BalanceView
+      balance={balance}
+      Linker={PageLink}
+      goToWalletManualWithdraw={goToWalletManualWithdraw}
+    />
+  );
 }
 export interface BalanceViewProps {
   balance: BalancesHook;
@@ -46,22 +63,26 @@ function formatPending(entry: Balance): JSX.Element {
 
   if (!Amounts.isZero(pendingIncoming)) {
     incoming = (
-      <span><i18n.Translate>
-        <span style={{ color: "darkgreen" }} title="incoming amount">
-          {"+"}
-          {renderAmount(entry.pendingIncoming)}
-        </span>{" "}
-      </i18n.Translate></span>
+      <span>
+        <i18n.Translate>
+          <span style={{ color: "darkgreen" }} title="incoming amount">
+            {"+"}
+            {renderAmount(entry.pendingIncoming)}
+          </span>{" "}
+        </i18n.Translate>
+      </span>
     );
   }
   if (!Amounts.isZero(pendingOutgoing)) {
     payment = (
-      <span><i18n.Translate>
-        <span style={{ color: "darkred" }} title="outgoing amount">
-          {"-"}
-          {renderAmount(entry.pendingOutgoing)}
-        </span>{" "}
-      </i18n.Translate></span>
+      <span>
+        <i18n.Translate>
+          <span style={{ color: "darkred" }} title="outgoing amount">
+            {"-"}
+            {renderAmount(entry.pendingOutgoing)}
+          </span>{" "}
+        </i18n.Translate>
+      </span>
     );
   }
 
@@ -80,76 +101,110 @@ function formatPending(entry: Balance): JSX.Element {
   );
 }
 
-
-export function BalanceView({ balance, Linker, goToWalletManualWithdraw }: 
BalanceViewProps) {
-
+export function BalanceView({
+  balance,
+  Linker,
+  goToWalletManualWithdraw,
+}: BalanceViewProps) {
   function Content() {
     if (!balance) {
-      return <span />
+      return <span />;
     }
 
     if (balance.hasError) {
-      return (<section>
-        <ErrorBox>{balance.message}</ErrorBox>
-        <p>
-          Click <Linker pageName="welcome">here</Linker> for help and
-          diagnostics.
-        </p>
-      </section>)
+      return (
+        <section>
+          <ErrorBox>{balance.message}</ErrorBox>
+          <p>
+            Click <Linker pageName="welcome">here</Linker> for help and
+            diagnostics.
+          </p>
+        </section>
+      );
     }
     if (balance.response.balances.length === 0) {
-      return (<section data-expanded>
-        <Middle>
-          <p><i18n.Translate>
-            You have no balance to show. Need some{" "}
-            <Linker pageName="/welcome">help</Linker> getting started?
-          </i18n.Translate></p>
-        </Middle>
-      </section>)
+      return (
+        <section data-expanded>
+          <Middle>
+            <p>
+              <i18n.Translate>
+                You have no balance to show. Need some{" "}
+                <Linker pageName="/welcome">help</Linker> getting started?
+              </i18n.Translate>
+            </p>
+          </Middle>
+        </section>
+      );
     }
-    return <section data-expanded data-centered>
-      <table style={{width:'100%'}}>{balance.response.balances.map((entry) => {
-        const av = Amounts.parseOrThrow(entry.available);
-        // Create our number formatter.
-        let formatter;
-        try {
-          formatter = new Intl.NumberFormat('en-US', {
-            style: 'currency',
-            currency: av.currency,
-            currencyDisplay: 'symbol'
-            // These options are needed to round to whole numbers if that's 
what you want.
-            //minimumFractionDigits: 0, // (this suffices for whole numbers, 
but will print 2500.10 as $2,500.1)
-            //maximumFractionDigits: 0, // (causes 2500.99 to be printed as 
$2,501)
-          });
-        } catch {
-          formatter = new Intl.NumberFormat('en-US', {
-            // style: 'currency',
-            // currency: av.currency,
-            // These options are needed to round to whole numbers if that's 
what you want.
-            //minimumFractionDigits: 0, // (this suffices for whole numbers, 
but will print 2500.10 as $2,500.1)
-            //maximumFractionDigits: 0, // (causes 2500.99 to be printed as 
$2,501)
-          });
-        }
-
-        const v = formatter.format(av.value + av.fraction / 
amountFractionalBase);
-        const fontSize = v.length < 8 ? '3em' : (v.length < 13 ? '2em' : '1em')
-        return (<tr>
-          <td style={{ height: 50, fontSize, width: '60%', textAlign: 'right', 
padding: 0 }}>{v}</td>
-          <td style={{ maxWidth: '2em', overflowX: 'hidden' 
}}>{av.currency}</td>
-          <td style={{ fontSize: 'small', color: 'gray' 
}}>{formatPending(entry)}</td>
-        </tr>
-        );
-      })}</table>
-    </section>
+    return (
+      <section data-expanded data-centered>
+        <table style={{ width: "100%" }}>
+          {balance.response.balances.map((entry) => {
+            const av = Amounts.parseOrThrow(entry.available);
+            // Create our number formatter.
+            let formatter;
+            try {
+              formatter = new Intl.NumberFormat("en-US", {
+                style: "currency",
+                currency: av.currency,
+                currencyDisplay: "symbol",
+                // These options are needed to round to whole numbers if 
that's what you want.
+                //minimumFractionDigits: 0, // (this suffices for whole 
numbers, but will print 2500.10 as $2,500.1)
+                //maximumFractionDigits: 0, // (causes 2500.99 to be printed 
as $2,501)
+              });
+            } catch {
+              formatter = new Intl.NumberFormat("en-US", {
+                // style: 'currency',
+                // currency: av.currency,
+                // These options are needed to round to whole numbers if 
that's what you want.
+                //minimumFractionDigits: 0, // (this suffices for whole 
numbers, but will print 2500.10 as $2,500.1)
+                //maximumFractionDigits: 0, // (causes 2500.99 to be printed 
as $2,501)
+              });
+            }
+
+            const v = formatter.format(
+              av.value + av.fraction / amountFractionalBase,
+            );
+            const fontSize =
+              v.length < 8 ? "3em" : v.length < 13 ? "2em" : "1em";
+            return (
+              <tr>
+                <td
+                  style={{
+                    height: 50,
+                    fontSize,
+                    width: "60%",
+                    textAlign: "right",
+                    padding: 0,
+                  }}
+                >
+                  {v}
+                </td>
+                <td style={{ maxWidth: "2em", overflowX: "hidden" }}>
+                  {av.currency}
+                </td>
+                <td style={{ fontSize: "small", color: "gray" }}>
+                  {formatPending(entry)}
+                </td>
+              </tr>
+            );
+          })}
+        </table>
+      </section>
+    );
   }
 
-  return <PopupBox>
-    {/* <section> */}
-    <Content />
-    {/* </section> */}
-    <footer>
-      <div />
-      <ButtonPrimary 
onClick={goToWalletManualWithdraw}>Withdraw</ButtonPrimary>
-    </footer>
-  </PopupBox>
+  return (
+    <PopupBox>
+      {/* <section> */}
+      <Content />
+      {/* </section> */}
+      <footer>
+        <div />
+        <ButtonPrimary onClick={goToWalletManualWithdraw}>
+          Withdraw
+        </ButtonPrimary>
+      </footer>
+    </PopupBox>
+  );
 }
diff --git a/packages/taler-wallet-webextension/src/popup/Debug.tsx 
b/packages/taler-wallet-webextension/src/popup/Debug.tsx
index ccc74746..8722c1cf 100644
--- a/packages/taler-wallet-webextension/src/popup/Debug.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Debug.tsx
@@ -19,13 +19,14 @@ import { Diagnostics } from "../components/Diagnostics";
 import { useDiagnostics } from "../hooks/useDiagnostics.js";
 import * as wxApi from "../wxApi";
 
-
 export function DeveloperPage(props: any): JSX.Element {
   const [status, timedOut] = useDiagnostics();
   return (
     <div>
       <p>Debug tools:</p>
-      <button onClick={openExtensionPage("/static/popup.html")}>wallet 
tab</button>
+      <button onClick={openExtensionPage("/static/popup.html")}>
+        wallet tab
+      </button>
       <br />
       <button onClick={confirmReset}>reset</button>
       <Diagnostics diagnostics={status} timedOut={timedOut} />
@@ -46,7 +47,7 @@ export async function confirmReset(): Promise<void> {
   if (
     confirm(
       "Do you want to IRREVOCABLY DESTROY everything inside your" +
-      " wallet and LOSE ALL YOUR COINS?",
+        " wallet and LOSE ALL YOUR COINS?",
     )
   ) {
     await wxApi.resetDb();
@@ -61,4 +62,3 @@ export function openExtensionPage(page: string) {
     });
   };
 }
-
diff --git a/packages/taler-wallet-webextension/src/popup/History.stories.tsx 
b/packages/taler-wallet-webextension/src/popup/History.stories.tsx
index daa263a8..95f4a547 100644
--- a/packages/taler-wallet-webextension/src/popup/History.stories.tsx
+++ b/packages/taler-wallet-webextension/src/popup/History.stories.tsx
@@ -15,135 +15,149 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
 import {
   PaymentStatus,
-  TransactionCommon, TransactionDeposit, TransactionPayment,
-  TransactionRefresh, TransactionRefund, TransactionTip, TransactionType,
+  TransactionCommon,
+  TransactionDeposit,
+  TransactionPayment,
+  TransactionRefresh,
+  TransactionRefund,
+  TransactionTip,
+  TransactionType,
   TransactionWithdrawal,
-  WithdrawalType
-} from '@gnu-taler/taler-util';
-import { createExample } from '../test-utils';
-import { HistoryView as TestedComponent } from './History';
+  WithdrawalType,
+} from "@gnu-taler/taler-util";
+import { createExample } from "../test-utils";
+import { HistoryView as TestedComponent } from "./History";
 
 export default {
-  title: 'popup/history/list',
+  title: "popup/history/list",
   component: TestedComponent,
 };
 
 const commonTransaction = {
-  amountRaw: 'USD:10',
-  amountEffective: 'USD:9',
+  amountRaw: "USD:10",
+  amountEffective: "USD:9",
   pending: false,
   timestamp: {
-    t_ms: new Date().getTime()
+    t_ms: new Date().getTime(),
   },
-  transactionId: '12',
-} as TransactionCommon
+  transactionId: "12",
+} as TransactionCommon;
 
 const exampleData = {
   withdraw: {
     ...commonTransaction,
     type: TransactionType.Withdrawal,
-    exchangeBaseUrl: 'http://exchange.demo.taler.net',
+    exchangeBaseUrl: "http://exchange.demo.taler.net";,
     withdrawalDetails: {
       confirmed: false,
-      exchangePaytoUris: ['payto://x-taler-bank/bank/account'],
+      exchangePaytoUris: ["payto://x-taler-bank/bank/account"],
       type: WithdrawalType.ManualTransfer,
-    }
+    },
   } as TransactionWithdrawal,
   payment: {
     ...commonTransaction,
-    amountEffective: 'USD:11',
+    amountEffective: "USD:11",
     type: TransactionType.Payment,
     info: {
-      contractTermsHash: 'ASDZXCASD',
+      contractTermsHash: "ASDZXCASD",
       merchant: {
-        name: 'the merchant',
+        name: "the merchant",
       },
-      orderId: '2021.167-03NPY6MCYMVGT',
+      orderId: "2021.167-03NPY6MCYMVGT",
       products: [],
-      summary: 'the summary',
-      fulfillmentMessage: '',
+      summary: "the summary",
+      fulfillmentMessage: "",
     },
-    proposalId: '1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0',
+    proposalId: "1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
     status: PaymentStatus.Accepted,
   } as TransactionPayment,
   deposit: {
     ...commonTransaction,
     type: TransactionType.Deposit,
-    depositGroupId: '#groupId',
-    targetPaytoUri: 'payto://x-taler-bank/bank/account',
+    depositGroupId: "#groupId",
+    targetPaytoUri: "payto://x-taler-bank/bank/account",
   } as TransactionDeposit,
   refresh: {
     ...commonTransaction,
     type: TransactionType.Refresh,
-    exchangeBaseUrl: 'http://exchange.taler',
+    exchangeBaseUrl: "http://exchange.taler";,
   } as TransactionRefresh,
   tip: {
     ...commonTransaction,
     type: TransactionType.Tip,
-    merchantBaseUrl: 'http://merchant.taler',
+    merchantBaseUrl: "http://merchant.taler";,
   } as TransactionTip,
   refund: {
     ...commonTransaction,
     type: TransactionType.Refund,
-    refundedTransactionId: 
'payment:1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0',
+    refundedTransactionId:
+      "payment:1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
     info: {
-      contractTermsHash: 'ASDZXCASD',
+      contractTermsHash: "ASDZXCASD",
       merchant: {
-        name: 'the merchant',
+        name: "the merchant",
       },
-      orderId: '2021.167-03NPY6MCYMVGT',
+      orderId: "2021.167-03NPY6MCYMVGT",
       products: [],
-      summary: 'the summary',
-      fulfillmentMessage: '',
+      summary: "the summary",
+      fulfillmentMessage: "",
     },
   } as TransactionRefund,
-}
+};
 
 export const EmptyWithBalance = createExample(TestedComponent, {
   list: [],
-  balances: [{
-    available: 'TESTKUDOS:10',
-    pendingIncoming: 'TESTKUDOS:0',
-    pendingOutgoing: 'TESTKUDOS:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }]
+  balances: [
+    {
+      available: "TESTKUDOS:10",
+      pendingIncoming: "TESTKUDOS:0",
+      pendingOutgoing: "TESTKUDOS:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+  ],
 });
 
 export const EmptyWithNoBalance = createExample(TestedComponent, {
   list: [],
-  balances: []
+  balances: [],
 });
 
 export const One = createExample(TestedComponent, {
   list: [exampleData.withdraw],
-  balances: [{
-    available: 'USD:10',
-    pendingIncoming: 'USD:0',
-    pendingOutgoing: 'USD:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }]
+  balances: [
+    {
+      available: "USD:10",
+      pendingIncoming: "USD:0",
+      pendingOutgoing: "USD:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+  ],
 });
 
 export const OnePending = createExample(TestedComponent, {
-  list: [{
-    ...exampleData.withdraw,
-    pending: true,
-  }],
-  balances: [{
-    available: 'USD:10',
-    pendingIncoming: 'USD:0',
-    pendingOutgoing: 'USD:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }]
+  list: [
+    {
+      ...exampleData.withdraw,
+      pending: true,
+    },
+  ],
+  balances: [
+    {
+      available: "USD:10",
+      pendingIncoming: "USD:0",
+      pendingOutgoing: "USD:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+  ],
 });
 
 export const Several = createExample(TestedComponent, {
@@ -157,13 +171,15 @@ export const Several = createExample(TestedComponent, {
     exampleData.tip,
     exampleData.deposit,
   ],
-  balances: [{
-    available: 'TESTKUDOS:10',
-    pendingIncoming: 'TESTKUDOS:0',
-    pendingOutgoing: 'TESTKUDOS:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }]
+  balances: [
+    {
+      available: "TESTKUDOS:10",
+      pendingIncoming: "TESTKUDOS:0",
+      pendingOutgoing: "TESTKUDOS:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+  ],
 });
 
 export const SeveralWithTwoCurrencies = createExample(TestedComponent, {
@@ -177,18 +193,20 @@ export const SeveralWithTwoCurrencies = 
createExample(TestedComponent, {
     exampleData.tip,
     exampleData.deposit,
   ],
-  balances: [{
-    available: 'TESTKUDOS:10',
-    pendingIncoming: 'TESTKUDOS:0',
-    pendingOutgoing: 'TESTKUDOS:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }, {
-    available: 'USD:10',
-    pendingIncoming: 'USD:0',
-    pendingOutgoing: 'USD:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }]
+  balances: [
+    {
+      available: "TESTKUDOS:10",
+      pendingIncoming: "TESTKUDOS:0",
+      pendingOutgoing: "TESTKUDOS:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+    {
+      available: "USD:10",
+      pendingIncoming: "USD:0",
+      pendingOutgoing: "USD:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+  ],
 });
-
diff --git a/packages/taler-wallet-webextension/src/popup/History.tsx 
b/packages/taler-wallet-webextension/src/popup/History.tsx
index 1447da9b..8fe6de16 100644
--- a/packages/taler-wallet-webextension/src/popup/History.tsx
+++ b/packages/taler-wallet-webextension/src/popup/History.tsx
@@ -14,7 +14,13 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { AmountString, Balance, i18n, Transaction, TransactionsResponse } from 
"@gnu-taler/taler-util";
+import {
+  AmountString,
+  Balance,
+  i18n,
+  Transaction,
+  TransactionsResponse,
+} from "@gnu-taler/taler-util";
 import { h, JSX } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import { PopupBox } from "../components/styled";
@@ -22,13 +28,14 @@ import { TransactionItem } from 
"../components/TransactionItem";
 import { useBalances } from "../hooks/useBalances";
 import * as wxApi from "../wxApi";
 
-
 export function HistoryPage(props: any): JSX.Element {
   const [transactions, setTransactions] = useState<
     TransactionsResponse | undefined
   >(undefined);
-  const balance = useBalances()
-  const balanceWithoutError = balance?.hasError ? [] : 
(balance?.response.balances || [])
+  const balance = useBalances();
+  const balanceWithoutError = balance?.hasError
+    ? []
+    : balance?.response.balances || [];
 
   useEffect(() => {
     const fetchData = async (): Promise<void> => {
@@ -42,46 +49,79 @@ export function HistoryPage(props: any): JSX.Element {
     return <div>Loading ...</div>;
   }
 
-  return <HistoryView balances={balanceWithoutError} 
list={[...transactions.transactions].reverse()} />;
+  return (
+    <HistoryView
+      balances={balanceWithoutError}
+      list={[...transactions.transactions].reverse()}
+    />
+  );
 }
 
 function amountToString(c: AmountString) {
-  const idx = c.indexOf(':')
-  return `${c.substring(idx + 1)} ${c.substring(0, idx)}`
+  const idx = c.indexOf(":");
+  return `${c.substring(idx + 1)} ${c.substring(0, idx)}`;
 }
 
-
-
-export function HistoryView({ list, balances }: { list: Transaction[], 
balances: Balance[] }) {
-  const multiCurrency = balances.length > 1
-  return <PopupBox noPadding>
-    {balances.length > 0 && <header>
-      {multiCurrency ? <div class="title">
-        Balance: <ul style={{ margin: 0 }}>
-          {balances.map(b => <li>{b.available}</li>)}
-        </ul>
-      </div> : <div class="title">
-        Balance: <span>{amountToString(balances[0].available)}</span>
-      </div>}
-    </header>}
-    {list.length === 0 ? <section data-expanded data-centered>
-      <p><i18n.Translate>
-        You have no history yet, here you will be able to check your last 
transactions.
-      </i18n.Translate></p>
-    </section> :
-      <section>
-        {list.slice(0, 3).map((tx, i) => (
-          <TransactionItem key={i} tx={tx} multiCurrency={multiCurrency} />
-        ))}
-      </section>
-    }
-    <footer style={{ justifyContent: 'space-around' }}>
-      {list.length > 0 &&
-        <a target="_blank"
-          rel="noopener noreferrer"
-          style={{ color: 'darkgreen', textDecoration: 'none' }}
-          href={chrome.extension ? 
chrome.extension.getURL(`/static/wallet.html#/history`) : '#'}>VIEW MORE 
TRANSACTIONS</a>
-      }
-    </footer>
-  </PopupBox>
+export function HistoryView({
+  list,
+  balances,
+}: {
+  list: Transaction[];
+  balances: Balance[];
+}) {
+  const multiCurrency = balances.length > 1;
+  return (
+    <PopupBox noPadding>
+      {balances.length > 0 && (
+        <header>
+          {multiCurrency ? (
+            <div class="title">
+              Balance:{" "}
+              <ul style={{ margin: 0 }}>
+                {balances.map((b) => (
+                  <li>{b.available}</li>
+                ))}
+              </ul>
+            </div>
+          ) : (
+            <div class="title">
+              Balance: <span>{amountToString(balances[0].available)}</span>
+            </div>
+          )}
+        </header>
+      )}
+      {list.length === 0 ? (
+        <section data-expanded data-centered>
+          <p>
+            <i18n.Translate>
+              You have no history yet, here you will be able to check your last
+              transactions.
+            </i18n.Translate>
+          </p>
+        </section>
+      ) : (
+        <section>
+          {list.slice(0, 3).map((tx, i) => (
+            <TransactionItem key={i} tx={tx} multiCurrency={multiCurrency} />
+          ))}
+        </section>
+      )}
+      <footer style={{ justifyContent: "space-around" }}>
+        {list.length > 0 && (
+          <a
+            target="_blank"
+            rel="noopener noreferrer"
+            style={{ color: "darkgreen", textDecoration: "none" }}
+            href={
+              chrome.extension
+                ? chrome.extension.getURL(`/static/wallet.html#/history`)
+                : "#"
+            }
+          >
+            VIEW MORE TRANSACTIONS
+          </a>
+        )}
+      </footer>
+    </PopupBox>
+  );
 }
diff --git a/packages/taler-wallet-webextension/src/popup/Popup.stories.tsx 
b/packages/taler-wallet-webextension/src/popup/Popup.stories.tsx
index cd443e9d..5009684c 100644
--- a/packages/taler-wallet-webextension/src/popup/Popup.stories.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Popup.stories.tsx
@@ -15,30 +15,29 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample } from '../test-utils';
-import { NavBar as TestedComponent } from '../NavigationBar';
+import { createExample } from "../test-utils";
+import { NavBar as TestedComponent } from "../NavigationBar";
 
 export default {
-  title: 'popup/header',
+  title: "popup/header",
   // component: TestedComponent,
   argTypes: {
-    onRetry: { action: 'onRetry' },
-    onDelete: { action: 'onDelete' },
-    onBack: { action: 'onBack' },
-  }
+    onRetry: { action: "onRetry" },
+    onDelete: { action: "onDelete" },
+    onBack: { action: "onBack" },
+  },
 };
 
-
 export const OnBalance = createExample(TestedComponent, {
-  devMode:false,
-  path:'/balance'
+  devMode: false,
+  path: "/balance",
 });
 
 export const OnHistoryWithDevMode = createExample(TestedComponent, {
-  devMode:true,
-  path:'/history'
+  devMode: true,
+  path: "/history",
 });
diff --git 
a/packages/taler-wallet-webextension/src/popup/ProviderAddConfirmProvider.stories.tsx
 
b/packages/taler-wallet-webextension/src/popup/ProviderAddConfirmProvider.stories.tsx
index de1f67b9..0cff7f75 100644
--- 
a/packages/taler-wallet-webextension/src/popup/ProviderAddConfirmProvider.stories.tsx
+++ 
b/packages/taler-wallet-webextension/src/popup/ProviderAddConfirmProvider.stories.tsx
@@ -15,38 +15,37 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample } from '../test-utils';
-import { ConfirmProviderView as TestedComponent } from './ProviderAddPage';
+import { createExample } from "../test-utils";
+import { ConfirmProviderView as TestedComponent } from "./ProviderAddPage";
 
 export default {
-  title: 'popup/backup/confirm',
+  title: "popup/backup/confirm",
   component: TestedComponent,
   argTypes: {
-    onRetry: { action: 'onRetry' },
-    onDelete: { action: 'onDelete' },
-    onBack: { action: 'onBack' },
-  }
+    onRetry: { action: "onRetry" },
+    onDelete: { action: "onDelete" },
+    onBack: { action: "onBack" },
+  },
 };
 
-
 export const DemoService = createExample(TestedComponent, {
-  url: 'https://sync.demo.taler.net/',
+  url: "https://sync.demo.taler.net/";,
   provider: {
-    annual_fee: 'KUDOS:0.1',
-    storage_limit_in_megabytes: 20, 
-    supported_protocol_version: '1'
-  }
+    annual_fee: "KUDOS:0.1",
+    storage_limit_in_megabytes: 20,
+    supported_protocol_version: "1",
+  },
 });
 
 export const FreeService = createExample(TestedComponent, {
-  url: 'https://sync.taler:9667/',
+  url: "https://sync.taler:9667/";,
   provider: {
-    annual_fee: 'ARS:0',
-    storage_limit_in_megabytes: 20, 
-    supported_protocol_version: '1'
-  }
+    annual_fee: "ARS:0",
+    storage_limit_in_megabytes: 20,
+    supported_protocol_version: "1",
+  },
 });
diff --git 
a/packages/taler-wallet-webextension/src/popup/ProviderAddSetUrl.stories.tsx 
b/packages/taler-wallet-webextension/src/popup/ProviderAddSetUrl.stories.tsx
index 2daf49e0..9a2f9705 100644
--- a/packages/taler-wallet-webextension/src/popup/ProviderAddSetUrl.stories.tsx
+++ b/packages/taler-wallet-webextension/src/popup/ProviderAddSetUrl.stories.tsx
@@ -15,39 +15,37 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample } from '../test-utils';
-import { SetUrlView as TestedComponent } from './ProviderAddPage';
+import { createExample } from "../test-utils";
+import { SetUrlView as TestedComponent } from "./ProviderAddPage";
 
 export default {
-  title: 'popup/backup/add',
+  title: "popup/backup/add",
   component: TestedComponent,
   argTypes: {
-    onRetry: { action: 'onRetry' },
-    onDelete: { action: 'onDelete' },
-    onBack: { action: 'onBack' },
-  }
+    onRetry: { action: "onRetry" },
+    onDelete: { action: "onDelete" },
+    onBack: { action: "onBack" },
+  },
 };
 
-
-export const Initial = createExample(TestedComponent, {
-}); 
+export const Initial = createExample(TestedComponent, {});
 
 export const WithValue = createExample(TestedComponent, {
-  initialValue: 'sync.demo.taler.net'
-}); 
+  initialValue: "sync.demo.taler.net",
+});
 
 export const WithConnectionError = createExample(TestedComponent, {
-  withError: 'Network error'
-}); 
+  withError: "Network error",
+});
 
 export const WithClientError = createExample(TestedComponent, {
-  withError: 'URL may not be right: (404) Not Found'
-}); 
+  withError: "URL may not be right: (404) Not Found",
+});
 
 export const WithServerError = createExample(TestedComponent, {
-  withError: 'Try another server: (500) Internal Server Error'
-}); 
+  withError: "Try another server: (500) Internal Server Error",
+});
diff --git 
a/packages/taler-wallet-webextension/src/popup/ProviderDetail.stories.tsx 
b/packages/taler-wallet-webextension/src/popup/ProviderDetail.stories.tsx
index 4416608f..fab21398 100644
--- a/packages/taler-wallet-webextension/src/popup/ProviderDetail.stories.tsx
+++ b/packages/taler-wallet-webextension/src/popup/ProviderDetail.stories.tsx
@@ -15,224 +15,221 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { ProviderPaymentType } from '@gnu-taler/taler-wallet-core';
-import { createExample } from '../test-utils';
-import { ProviderView as TestedComponent } from './ProviderDetailPage';
+import { ProviderPaymentType } from "@gnu-taler/taler-wallet-core";
+import { createExample } from "../test-utils";
+import { ProviderView as TestedComponent } from "./ProviderDetailPage";
 
 export default {
-  title: 'popup/backup/details',
+  title: "popup/backup/details",
   component: TestedComponent,
   argTypes: {
-    onRetry: { action: 'onRetry' },
-    onDelete: { action: 'onDelete' },
-    onBack: { action: 'onBack' },
-  }
+    onRetry: { action: "onRetry" },
+    onDelete: { action: "onDelete" },
+    onBack: { action: "onBack" },
+  },
 };
 
-
 export const Active = createExample(TestedComponent, {
   info: {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
-    },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
+    active: true,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.taler:9967/";,
+    lastSuccessfulBackupTimestamp: {
+      t_ms: 1625063925078,
+    },
+    paymentProposalIds: [
+      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
     ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
-    },
-    "terms": {
-      "annualFee": "EUR:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+    paymentStatus: {
+      type: ProviderPaymentType.Paid,
+      paidUntil: {
+        t_ms: 1656599921000,
+      },
+    },
+    terms: {
+      annualFee: "EUR:1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const ActiveErrorSync = createExample(TestedComponent, {
   info: {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
+    active: true,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.taler:9967/";,
+    lastSuccessfulBackupTimestamp: {
+      t_ms: 1625063925078,
     },
     lastAttemptedBackupTimestamp: {
-      "t_ms": 1625063925078
+      t_ms: 1625063925078,
     },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
+    paymentProposalIds: [
+      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
     ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
+    paymentStatus: {
+      type: ProviderPaymentType.Paid,
+      paidUntil: {
+        t_ms: 1656599921000,
+      },
     },
     lastError: {
       code: 2002,
-      details: 'details',
-      hint: 'error hint from the server',
-      message: 'message'
-    },
-    "terms": {
-      "annualFee": "EUR:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+      details: "details",
+      hint: "error hint from the server",
+      message: "message",
+    },
+    terms: {
+      annualFee: "EUR:1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const ActiveBackupProblemUnreadable = createExample(TestedComponent, {
   info: {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
-    },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
+    active: true,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.taler:9967/";,
+    lastSuccessfulBackupTimestamp: {
+      t_ms: 1625063925078,
+    },
+    paymentProposalIds: [
+      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
     ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
+    paymentStatus: {
+      type: ProviderPaymentType.Paid,
+      paidUntil: {
+        t_ms: 1656599921000,
+      },
     },
     backupProblem: {
-      type: 'backup-unreadable'
-    },
-    "terms": {
-      "annualFee": "EUR:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+      type: "backup-unreadable",
+    },
+    terms: {
+      annualFee: "EUR:1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const ActiveBackupProblemDevice = createExample(TestedComponent, {
   info: {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
-    },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
+    active: true,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.taler:9967/";,
+    lastSuccessfulBackupTimestamp: {
+      t_ms: 1625063925078,
+    },
+    paymentProposalIds: [
+      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
     ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
+    paymentStatus: {
+      type: ProviderPaymentType.Paid,
+      paidUntil: {
+        t_ms: 1656599921000,
+      },
     },
     backupProblem: {
-      type: 'backup-conflicting-device',
-      myDeviceId: 'my-device-id',
-      otherDeviceId: 'other-device-id',
+      type: "backup-conflicting-device",
+      myDeviceId: "my-device-id",
+      otherDeviceId: "other-device-id",
       backupTimestamp: {
-        "t_ms": 1656599921000
-      }
-    },
-    "terms": {
-      "annualFee": "EUR:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+        t_ms: 1656599921000,
+      },
+    },
+    terms: {
+      annualFee: "EUR:1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const InactiveUnpaid = createExample(TestedComponent, {
   info: {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Unpaid,
-    },
-    "terms": {
-      "annualFee": "EUR:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+    active: false,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+    paymentProposalIds: [],
+    paymentStatus: {
+      type: ProviderPaymentType.Unpaid,
+    },
+    terms: {
+      annualFee: "EUR:0.1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const InactiveInsufficientBalance = createExample(TestedComponent, {
   info: {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.InsufficientBalance,
-    },
-    "terms": {
-      "annualFee": "EUR:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+    active: false,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+    paymentProposalIds: [],
+    paymentStatus: {
+      type: ProviderPaymentType.InsufficientBalance,
+    },
+    terms: {
+      annualFee: "EUR:0.1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const InactivePending = createExample(TestedComponent, {
   info: {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Pending,
-    },
-    "terms": {
-      "annualFee": "EUR:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+    active: false,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+    paymentProposalIds: [],
+    paymentStatus: {
+      type: ProviderPaymentType.Pending,
+    },
+    terms: {
+      annualFee: "EUR:0.1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
-
 export const ActiveTermsChanged = createExample(TestedComponent, {
   info: {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.TermsChanged,
+    active: true,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+    paymentProposalIds: [],
+    paymentStatus: {
+      type: ProviderPaymentType.TermsChanged,
       paidUntil: {
-        t_ms: 1656599921000
+        t_ms: 1656599921000,
       },
       newTerms: {
-        "annualFee": "EUR:10",
-        "storageLimitInMegabytes": 8,
-        "supportedProtocolVersion": "0.0"
+        annualFee: "EUR:10",
+        storageLimitInMegabytes: 8,
+        supportedProtocolVersion: "0.0",
       },
       oldTerms: {
-        "annualFee": "EUR:0.1",
-        "storageLimitInMegabytes": 16,
-        "supportedProtocolVersion": "0.0"
-      }
-    },
-    "terms": {
-      "annualFee": "EUR:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+        annualFee: "EUR:0.1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
+    },
+    terms: {
+      annualFee: "EUR:0.1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
-
diff --git 
a/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx 
b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx
index 04adbb21..9617c9a4 100644
--- a/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx
+++ b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx
@@ -14,13 +14,23 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 
-
 import { i18n, Timestamp } from "@gnu-taler/taler-util";
-import { ProviderInfo, ProviderPaymentStatus, ProviderPaymentType } from 
"@gnu-taler/taler-wallet-core";
+import {
+  ProviderInfo,
+  ProviderPaymentStatus,
+  ProviderPaymentType,
+} from "@gnu-taler/taler-wallet-core";
 import { format, formatDuration, intervalToDuration } from "date-fns";
 import { Fragment, VNode, h } from "preact";
 import { ErrorMessage } from "../components/ErrorMessage";
-import { Button, ButtonDestructive, ButtonPrimary, PaymentStatus, PopupBox, 
SmallLightText } from "../components/styled";
+import {
+  Button,
+  ButtonDestructive,
+  ButtonPrimary,
+  PaymentStatus,
+  PopupBox,
+  SmallLightText,
+} from "../components/styled";
 import { useProviderStatus } from "../hooks/useProviderStatus";
 
 interface Props {
@@ -29,20 +39,29 @@ interface Props {
 }
 
 export function ProviderDetailPage({ pid, onBack }: Props): VNode {
-  const status = useProviderStatus(pid)
+  const status = useProviderStatus(pid);
   if (!status) {
-    return <div><i18n.Translate>Loading...</i18n.Translate></div>
+    return (
+      <div>
+        <i18n.Translate>Loading...</i18n.Translate>
+      </div>
+    );
   }
   if (!status.info) {
-    onBack()
-    return <div />
+    onBack();
+    return <div />;
   }
-  return <ProviderView info={status.info}
-    onSync={status.sync}
-    onDelete={() => status.remove().then(onBack)}
-    onBack={onBack}
-    onExtend={() => { null }}
-  />;
+  return (
+    <ProviderView
+      info={status.info}
+      onSync={status.sync}
+      onDelete={() => status.remove().then(onBack)}
+      onBack={onBack}
+      onExtend={() => {
+        null;
+      }}
+    />
+  );
 }
 
 export interface ViewProps {
@@ -53,124 +72,185 @@ export interface ViewProps {
   onExtend: () => void;
 }
 
-export function ProviderView({ info, onDelete, onSync, onBack, onExtend }: 
ViewProps): VNode {
-  const lb = info?.lastSuccessfulBackupTimestamp
-  const isPaid = info.paymentStatus.type === ProviderPaymentType.Paid || 
info.paymentStatus.type === ProviderPaymentType.TermsChanged
+export function ProviderView({
+  info,
+  onDelete,
+  onSync,
+  onBack,
+  onExtend,
+}: ViewProps): VNode {
+  const lb = info?.lastSuccessfulBackupTimestamp;
+  const isPaid =
+    info.paymentStatus.type === ProviderPaymentType.Paid ||
+    info.paymentStatus.type === ProviderPaymentType.TermsChanged;
   return (
     <PopupBox>
       <Error info={info} />
       <header>
-        <h3>{info.name} 
<SmallLightText>{info.syncProviderBaseUrl}</SmallLightText></h3>
-        <PaymentStatus color={isPaid ? 'rgb(28, 184, 65)' : 'rgb(202, 60, 
60)'}>{isPaid ? 'Paid' : 'Unpaid'}</PaymentStatus>
+        <h3>
+          {info.name}{" "}
+          <SmallLightText>{info.syncProviderBaseUrl}</SmallLightText>
+        </h3>
+        <PaymentStatus color={isPaid ? "rgb(28, 184, 65)" : "rgb(202, 60, 
60)"}>
+          {isPaid ? "Paid" : "Unpaid"}
+        </PaymentStatus>
       </header>
       <section>
-        <p><b>Last backup:</b> {lb == null || lb.t_ms == "never" ? "never" : 
format(lb.t_ms, 'dd MMM yyyy')} </p>
-        <ButtonPrimary onClick={onSync}><i18n.Translate>Back 
up</i18n.Translate></ButtonPrimary>
-        {info.terms && <Fragment>
-          <p><b>Provider fee:</b> {info.terms && info.terms.annualFee} per 
year</p>
-        </Fragment>
-        }
+        <p>
+          <b>Last backup:</b>{" "}
+          {lb == null || lb.t_ms == "never"
+            ? "never"
+            : format(lb.t_ms, "dd MMM yyyy")}{" "}
+        </p>
+        <ButtonPrimary onClick={onSync}>
+          <i18n.Translate>Back up</i18n.Translate>
+        </ButtonPrimary>
+        {info.terms && (
+          <Fragment>
+            <p>
+              <b>Provider fee:</b> {info.terms && info.terms.annualFee} per 
year
+            </p>
+          </Fragment>
+        )}
         <p>{descriptionByStatus(info.paymentStatus)}</p>
-        <ButtonPrimary disabled 
onClick={onExtend}><i18n.Translate>Extend</i18n.Translate></ButtonPrimary>
-
-        {info.paymentStatus.type === ProviderPaymentType.TermsChanged && <div>
-          <p><i18n.Translate>terms has changed, extending the service will 
imply accepting the new terms of service</i18n.Translate></p>
-          <table>
-            <thead>
-              <tr>
-                <td></td>
-                <td><i18n.Translate>old</i18n.Translate></td>
-                <td> -&gt;</td>
-                <td><i18n.Translate>new</i18n.Translate></td>
-              </tr>
-            </thead>
-            <tbody>
-
-              <tr>
-                <td><i18n.Translate>fee</i18n.Translate></td>
-                <td>{info.paymentStatus.oldTerms.annualFee}</td>
-                <td>-&gt;</td>
-                <td>{info.paymentStatus.newTerms.annualFee}</td>
-              </tr>
-              <tr>
-                <td><i18n.Translate>storage</i18n.Translate></td>
-                <td>{info.paymentStatus.oldTerms.storageLimitInMegabytes}</td>
-                <td>-&gt;</td>
-                <td>{info.paymentStatus.newTerms.storageLimitInMegabytes}</td>
-              </tr>
-            </tbody>
-          </table>
-        </div>}
+        <ButtonPrimary disabled onClick={onExtend}>
+          <i18n.Translate>Extend</i18n.Translate>
+        </ButtonPrimary>
 
+        {info.paymentStatus.type === ProviderPaymentType.TermsChanged && (
+          <div>
+            <p>
+              <i18n.Translate>
+                terms has changed, extending the service will imply accepting
+                the new terms of service
+              </i18n.Translate>
+            </p>
+            <table>
+              <thead>
+                <tr>
+                  <td></td>
+                  <td>
+                    <i18n.Translate>old</i18n.Translate>
+                  </td>
+                  <td> -&gt;</td>
+                  <td>
+                    <i18n.Translate>new</i18n.Translate>
+                  </td>
+                </tr>
+              </thead>
+              <tbody>
+                <tr>
+                  <td>
+                    <i18n.Translate>fee</i18n.Translate>
+                  </td>
+                  <td>{info.paymentStatus.oldTerms.annualFee}</td>
+                  <td>-&gt;</td>
+                  <td>{info.paymentStatus.newTerms.annualFee}</td>
+                </tr>
+                <tr>
+                  <td>
+                    <i18n.Translate>storage</i18n.Translate>
+                  </td>
+                  
<td>{info.paymentStatus.oldTerms.storageLimitInMegabytes}</td>
+                  <td>-&gt;</td>
+                  
<td>{info.paymentStatus.newTerms.storageLimitInMegabytes}</td>
+                </tr>
+              </tbody>
+            </table>
+          </div>
+        )}
       </section>
       <footer>
-        <Button onClick={onBack}><i18n.Translate> &lt; 
back</i18n.Translate></Button>
+        <Button onClick={onBack}>
+          <i18n.Translate> &lt; back</i18n.Translate>
+        </Button>
         <div>
-          <ButtonDestructive onClick={onDelete}><i18n.Translate>remove 
provider</i18n.Translate></ButtonDestructive>
+          <ButtonDestructive onClick={onDelete}>
+            <i18n.Translate>remove provider</i18n.Translate>
+          </ButtonDestructive>
         </div>
       </footer>
     </PopupBox>
-  )
+  );
 }
 
 function daysSince(d?: Timestamp) {
-  if (!d || d.t_ms === 'never') return 'never synced'
+  if (!d || d.t_ms === "never") return "never synced";
   const duration = intervalToDuration({
     start: d.t_ms,
     end: new Date(),
-  })
+  });
   const str = formatDuration(duration, {
-    delimiter: ', ',
+    delimiter: ", ",
     format: [
-      duration?.years ? i18n.str`years` : (
-        duration?.months ? i18n.str`months` : (
-          duration?.days ? i18n.str`days` : (
-            duration?.hours ? i18n.str`hours` : (
-              duration?.minutes ? i18n.str`minutes` : i18n.str`seconds`
-            )
-          )
-        )
-      )
-    ]
-  })
-  return `synced ${str} ago`
+      duration?.years
+        ? i18n.str`years`
+        : duration?.months
+        ? i18n.str`months`
+        : duration?.days
+        ? i18n.str`days`
+        : duration?.hours
+        ? i18n.str`hours`
+        : duration?.minutes
+        ? i18n.str`minutes`
+        : i18n.str`seconds`,
+    ],
+  });
+  return `synced ${str} ago`;
 }
 
 function Error({ info }: { info: ProviderInfo }) {
   if (info.lastError) {
-    return <ErrorMessage title={info.lastError.hint} />
+    return <ErrorMessage title={info.lastError.hint} />;
   }
   if (info.backupProblem) {
     switch (info.backupProblem.type) {
       case "backup-conflicting-device":
-        return <ErrorMessage title={<Fragment>
-          <i18n.Translate>There is conflict with another backup from 
<b>{info.backupProblem.otherDeviceId}</b></i18n.Translate>
-        </Fragment>} />
+        return (
+          <ErrorMessage
+            title={
+              <Fragment>
+                <i18n.Translate>
+                  There is conflict with another backup from{" "}
+                  <b>{info.backupProblem.otherDeviceId}</b>
+                </i18n.Translate>
+              </Fragment>
+            }
+          />
+        );
       case "backup-unreadable":
-        return <ErrorMessage title="Backup is not readable" />
+        return <ErrorMessage title="Backup is not readable" />;
       default:
-        return <ErrorMessage title={<Fragment>
-          <i18n.Translate>Unknown backup problem: 
{JSON.stringify(info.backupProblem)}</i18n.Translate>
-        </Fragment>} />
+        return (
+          <ErrorMessage
+            title={
+              <Fragment>
+                <i18n.Translate>
+                  Unknown backup problem: {JSON.stringify(info.backupProblem)}
+                </i18n.Translate>
+              </Fragment>
+            }
+          />
+        );
     }
   }
-  return null
+  return null;
 }
 
 function colorByStatus(status: ProviderPaymentType) {
   switch (status) {
     case ProviderPaymentType.InsufficientBalance:
-      return 'rgb(223, 117, 20)'
+      return "rgb(223, 117, 20)";
     case ProviderPaymentType.Unpaid:
-      return 'rgb(202, 60, 60)'
+      return "rgb(202, 60, 60)";
     case ProviderPaymentType.Paid:
-      return 'rgb(28, 184, 65)'
+      return "rgb(28, 184, 65)";
     case ProviderPaymentType.Pending:
-      return 'gray'
+      return "gray";
     case ProviderPaymentType.InsufficientBalance:
-      return 'rgb(202, 60, 60)'
+      return "rgb(202, 60, 60)";
     case ProviderPaymentType.TermsChanged:
-      return 'rgb(202, 60, 60)'
+      return "rgb(202, 60, 60)";
   }
 }
 
@@ -180,16 +260,19 @@ function descriptionByStatus(status: 
ProviderPaymentStatus) {
     // return i18n.str`not paid yet`
     case ProviderPaymentType.Paid:
     case ProviderPaymentType.TermsChanged:
-      if (status.paidUntil.t_ms === 'never') {
-        return i18n.str`service paid`
+      if (status.paidUntil.t_ms === "never") {
+        return i18n.str`service paid`;
       } else {
-        return <Fragment>
-          <b>Backup valid until:</b> {format(status.paidUntil.t_ms, 'dd MMM 
yyyy')}
-        </Fragment>
+        return (
+          <Fragment>
+            <b>Backup valid until:</b>{" "}
+            {format(status.paidUntil.t_ms, "dd MMM yyyy")}
+          </Fragment>
+        );
       }
     case ProviderPaymentType.Unpaid:
     case ProviderPaymentType.InsufficientBalance:
     case ProviderPaymentType.Pending:
-      return ''
+      return "";
   }
 }
diff --git a/packages/taler-wallet-webextension/src/popup/Settings.stories.tsx 
b/packages/taler-wallet-webextension/src/popup/Settings.stories.tsx
index 06e33c9d..ae8e54ba 100644
--- a/packages/taler-wallet-webextension/src/popup/Settings.stories.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Settings.stories.tsx
@@ -15,29 +15,28 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample } from '../test-utils';
-import { SettingsView as TestedComponent } from './Settings';
+import { createExample } from "../test-utils";
+import { SettingsView as TestedComponent } from "./Settings";
 
 export default {
-  title: 'popup/settings',
+  title: "popup/settings",
   component: TestedComponent,
   argTypes: {
     setDeviceName: () => Promise.resolve(),
-  }
+  },
 };
 
 export const AllOff = createExample(TestedComponent, {
-  deviceName: 'this-is-the-device-name',
+  deviceName: "this-is-the-device-name",
   setDeviceName: () => Promise.resolve(),
 });
 
 export const OneChecked = createExample(TestedComponent, {
-  deviceName: 'this-is-the-device-name',
+  deviceName: "this-is-the-device-name",
   permissionsEnabled: true,
   setDeviceName: () => Promise.resolve(),
 });
-
diff --git a/packages/taler-wallet-webextension/src/popup/Settings.tsx 
b/packages/taler-wallet-webextension/src/popup/Settings.tsx
index 8595c87f..3b83f076 100644
--- a/packages/taler-wallet-webextension/src/popup/Settings.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Settings.tsx
@@ -14,7 +14,6 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 
-
 import { i18n } from "@gnu-taler/taler-util";
 import { VNode, h } from "preact";
 import { Checkbox } from "../components/Checkbox";
@@ -28,15 +27,21 @@ import { useLang } from "../hooks/useLang";
 
 export function SettingsPage(): VNode {
   const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
-  const { devMode, toggleDevMode } = useDevContext()
-  const { name, update } = useBackupDeviceName()
-  const [lang, changeLang] = useLang()
-  return <SettingsView
-    lang={lang} changeLang={changeLang}
-    deviceName={name} setDeviceName={update}
-    permissionsEnabled={permissionsEnabled} 
togglePermissions={togglePermissions}
-    developerMode={devMode} toggleDeveloperMode={toggleDevMode}
-  />;
+  const { devMode, toggleDevMode } = useDevContext();
+  const { name, update } = useBackupDeviceName();
+  const [lang, changeLang] = useLang();
+  return (
+    <SettingsView
+      lang={lang}
+      changeLang={changeLang}
+      deviceName={name}
+      setDeviceName={update}
+      permissionsEnabled={permissionsEnabled}
+      togglePermissions={togglePermissions}
+      developerMode={devMode}
+      toggleDeveloperMode={toggleDevMode}
+    />
+  );
 }
 
 export interface ViewProps {
@@ -50,23 +55,31 @@ export interface ViewProps {
   toggleDeveloperMode: () => void;
 }
 
-import { strings as messages } from '../i18n/strings'
+import { strings as messages } from "../i18n/strings";
 
 type LangsNames = {
-  [P in keyof typeof messages]: string
-}
+  [P in keyof typeof messages]: string;
+};
 
 const names: LangsNames = {
-  es: 'Español [es]',
-  en: 'English [en]',
-  fr: 'Français [fr]',
-  de: 'Deutsch [de]',
-  sv: 'Svenska [sv]',
-  it: 'Italiano [it]',
-}
-
+  es: "Español [es]",
+  en: "English [en]",
+  fr: "Français [fr]",
+  de: "Deutsch [de]",
+  sv: "Svenska [sv]",
+  it: "Italiano [it]",
+};
 
-export function SettingsView({ lang, changeLang, deviceName, setDeviceName, 
permissionsEnabled, togglePermissions, developerMode, toggleDeveloperMode }: 
ViewProps): VNode {
+export function SettingsView({
+  lang,
+  changeLang,
+  deviceName,
+  setDeviceName,
+  permissionsEnabled,
+  togglePermissions,
+  developerMode,
+  toggleDeveloperMode,
+}: ViewProps): VNode {
   return (
     <PopupBox>
       <section>
@@ -86,25 +99,39 @@ export function SettingsView({ lang, changeLang, 
deviceName, setDeviceName, perm
           label={i18n.str`Device name`}
           description="(This is how you will recognize the wallet in the 
backup provider)"
         /> */}
-        <h2><i18n.Translate>Permissions</i18n.Translate></h2>
-        <Checkbox label="Automatically open wallet based on page content"
+        <h2>
+          <i18n.Translate>Permissions</i18n.Translate>
+        </h2>
+        <Checkbox
+          label="Automatically open wallet based on page content"
           name="perm"
           description="(Enabling this option below will make using the wallet 
faster, but requires more permissions from your browser.)"
-          enabled={permissionsEnabled} onToggle={togglePermissions}
+          enabled={permissionsEnabled}
+          onToggle={togglePermissions}
         />
         <h2>Config</h2>
-        <Checkbox label="Developer mode"
+        <Checkbox
+          label="Developer mode"
           name="devMode"
           description="(More options and information useful for debugging)"
-          enabled={developerMode} onToggle={toggleDeveloperMode}
+          enabled={developerMode}
+          onToggle={toggleDeveloperMode}
         />
       </section>
-      <footer style={{ justifyContent: 'space-around' }}>
-        <a target="_blank"
+      <footer style={{ justifyContent: "space-around" }}>
+        <a
+          target="_blank"
           rel="noopener noreferrer"
-          style={{ color: 'darkgreen', textDecoration: 'none' }}
-          href={chrome.extension ? 
chrome.extension.getURL(`/static/wallet.html#/settings`) : '#'}>VIEW MORE 
SETTINGS</a>
+          style={{ color: "darkgreen", textDecoration: "none" }}
+          href={
+            chrome.extension
+              ? chrome.extension.getURL(`/static/wallet.html#/settings`)
+              : "#"
+          }
+        >
+          VIEW MORE SETTINGS
+        </a>
       </footer>
     </PopupBox>
-  )
-}
\ No newline at end of file
+  );
+}
diff --git 
a/packages/taler-wallet-webextension/src/popup/TalerActionFound.stories.tsx 
b/packages/taler-wallet-webextension/src/popup/TalerActionFound.stories.tsx
index 88c7c725..f20403d6 100644
--- a/packages/taler-wallet-webextension/src/popup/TalerActionFound.stories.tsx
+++ b/packages/taler-wallet-webextension/src/popup/TalerActionFound.stories.tsx
@@ -15,38 +15,38 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample } from '../test-utils';
-import { TalerActionFound as TestedComponent } from './TalerActionFound';
+import { createExample } from "../test-utils";
+import { TalerActionFound as TestedComponent } from "./TalerActionFound";
 
 export default {
-  title: 'popup/TalerActionFound',
+  title: "popup/TalerActionFound",
   component: TestedComponent,
 };
 
 export const PayAction = createExample(TestedComponent, {
-  url: 'taler://pay/something'
+  url: "taler://pay/something",
 });
 
 export const WithdrawalAction = createExample(TestedComponent, {
-  url: 'taler://withdraw/something'
+  url: "taler://withdraw/something",
 });
 
 export const TipAction = createExample(TestedComponent, {
-  url: 'taler://tip/something'
+  url: "taler://tip/something",
 });
 
 export const NotifyAction = createExample(TestedComponent, {
-  url: 'taler://notify-reserve/something'
+  url: "taler://notify-reserve/something",
 });
 
 export const RefundAction = createExample(TestedComponent, {
-  url: 'taler://refund/something'
+  url: "taler://refund/something",
 });
 
 export const InvalidAction = createExample(TestedComponent, {
-  url: 'taler://something/asd'
+  url: "taler://something/asd",
 });
diff --git a/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx 
b/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx
index ef0ec341..cbdcbeb1 100644
--- a/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx
+++ b/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx
@@ -1,5 +1,31 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
 import { classifyTalerUri, TalerUriType } from "@gnu-taler/taler-util";
-import { ButtonPrimary, ButtonSuccess, PopupBox } from 
"../components/styled/index";
+import {
+  ButtonPrimary,
+  ButtonSuccess,
+  PopupBox,
+} from "../components/styled/index";
+import { h } from "preact";
 
 export interface Props {
   url: string;
@@ -8,54 +34,89 @@ export interface Props {
 
 export function TalerActionFound({ url, onDismiss }: Props) {
   const uriType = classifyTalerUri(url);
-  return <PopupBox>
-    <section>
-      <h1>Taler Action </h1>
-      {uriType === TalerUriType.TalerPay && <div>
-        <p>This page has pay action.</p>
-        <ButtonSuccess onClick={() => { chrome.tabs.create({ "url": 
actionForTalerUri(uriType, url) }); }}>
-          Open pay page
-        </ButtonSuccess>
-      </div>}
-      {uriType === TalerUriType.TalerWithdraw && <div>
-        <p>This page has a withdrawal action.</p>
-        <ButtonSuccess onClick={() => { chrome.tabs.create({ "url": 
actionForTalerUri(uriType, url) }); }}>
-          Open withdraw page
-        </ButtonSuccess>
-      </div>}
-      {uriType === TalerUriType.TalerTip && <div>
-        <p>This page has a tip action.</p>
-        <ButtonSuccess onClick={() => { chrome.tabs.create({ "url": 
actionForTalerUri(uriType, url) }); }}>
-          Open tip page
-        </ButtonSuccess>
-      </div>}
-      {uriType === TalerUriType.TalerNotifyReserve && <div>
-        <p>This page has a notify reserve action.</p>
-        <ButtonSuccess onClick={() => { chrome.tabs.create({ "url": 
actionForTalerUri(uriType, url) }); }}>
-          Notify
-        </ButtonSuccess>
-      </div>}
-      {uriType === TalerUriType.TalerRefund && <div>
-        <p>This page has a refund action.</p>
-        <ButtonSuccess onClick={() => { chrome.tabs.create({ "url": 
actionForTalerUri(uriType, url) }); }}>
-          Open refund page
-        </ButtonSuccess>
-      </div>}
-      {uriType === TalerUriType.Unknown && <div>
-        <p>This page has a malformed taler uri.</p>
-        <p>{url}</p>
-      </div>}
-
-    </section>
-    <footer>
-      <div />
-      <ButtonPrimary onClick={() => onDismiss()}> Dismiss </ButtonPrimary>
-    </footer>
-  </PopupBox>;
-
+  return (
+    <PopupBox>
+      <section>
+        <h1>Taler Action </h1>
+        {uriType === TalerUriType.TalerPay && (
+          <div>
+            <p>This page has pay action.</p>
+            <ButtonSuccess
+              onClick={() => {
+                chrome.tabs.create({ url: actionForTalerUri(uriType, url) });
+              }}
+            >
+              Open pay page
+            </ButtonSuccess>
+          </div>
+        )}
+        {uriType === TalerUriType.TalerWithdraw && (
+          <div>
+            <p>This page has a withdrawal action.</p>
+            <ButtonSuccess
+              onClick={() => {
+                chrome.tabs.create({ url: actionForTalerUri(uriType, url) });
+              }}
+            >
+              Open withdraw page
+            </ButtonSuccess>
+          </div>
+        )}
+        {uriType === TalerUriType.TalerTip && (
+          <div>
+            <p>This page has a tip action.</p>
+            <ButtonSuccess
+              onClick={() => {
+                chrome.tabs.create({ url: actionForTalerUri(uriType, url) });
+              }}
+            >
+              Open tip page
+            </ButtonSuccess>
+          </div>
+        )}
+        {uriType === TalerUriType.TalerNotifyReserve && (
+          <div>
+            <p>This page has a notify reserve action.</p>
+            <ButtonSuccess
+              onClick={() => {
+                chrome.tabs.create({ url: actionForTalerUri(uriType, url) });
+              }}
+            >
+              Notify
+            </ButtonSuccess>
+          </div>
+        )}
+        {uriType === TalerUriType.TalerRefund && (
+          <div>
+            <p>This page has a refund action.</p>
+            <ButtonSuccess
+              onClick={() => {
+                chrome.tabs.create({ url: actionForTalerUri(uriType, url) });
+              }}
+            >
+              Open refund page
+            </ButtonSuccess>
+          </div>
+        )}
+        {uriType === TalerUriType.Unknown && (
+          <div>
+            <p>This page has a malformed taler uri.</p>
+            <p>{url}</p>
+          </div>
+        )}
+      </section>
+      <footer>
+        <div />
+        <ButtonPrimary onClick={() => onDismiss()}> Dismiss </ButtonPrimary>
+      </footer>
+    </PopupBox>
+  );
 }
 
-function actionForTalerUri(uriType: TalerUriType, talerUri: string): string | 
undefined {
+function actionForTalerUri(
+  uriType: TalerUriType,
+  talerUri: string,
+): string | undefined {
   switch (uriType) {
     case TalerUriType.TalerWithdraw:
       return makeExtensionUrlWithParams("static/wallet.html#/withdraw", {
@@ -91,8 +152,10 @@ function makeExtensionUrlWithParams(
 ): string {
   const innerUrl = new URL(chrome.extension.getURL("/" + url));
   if (params) {
-    const hParams = Object.keys(params).map(k => `${k}=${params[k]}`).join('&')
-    innerUrl.hash = innerUrl.hash + '?' + hParams
+    const hParams = Object.keys(params)
+      .map((k) => `${k}=${params[k]}`)
+      .join("&");
+    innerUrl.hash = innerUrl.hash + "?" + hParams;
   }
   return innerUrl.href;
 }
diff --git a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx 
b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
index 070df554..a5723ccb 100644
--- a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
+++ b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
@@ -22,19 +22,17 @@
 
 import { setupI18n } from "@gnu-taler/taler-util";
 import { createHashHistory } from "history";
-import { render, h, VNode } from "preact";
-import Router, { route, Route, getCurrentUrl } from "preact-router";
-import { useEffect, useState } from "preact/hooks";
+import { render, h } from "preact";
+import Router, { route, Route } from "preact-router";
+import { useEffect } from "preact/hooks";
 import { DevContextProvider } from "./context/devContext";
 import { useTalerActionURL } from "./hooks/useTalerActionURL";
 import { strings } from "./i18n/strings";
+import { Pages, WalletNavBar } from "./NavigationBar";
 import { BackupPage } from "./popup/BackupPage";
 import { BalancePage } from "./popup/BalancePage";
-import { DeveloperPage as DeveloperPage } from "./popup/Debug";
+import { DeveloperPage } from "./popup/Debug";
 import { HistoryPage } from "./popup/History";
-import {
-  Pages, WalletNavBar
-} from "./NavigationBar";
 import { ProviderAddPage } from "./popup/ProviderAddPage";
 import { ProviderDetailPage } from "./popup/ProviderDetailPage";
 import { SettingsPage } from "./popup/Settings";
@@ -64,11 +62,11 @@ if (document.readyState === "loading") {
 }
 
 function Application() {
-  const [talerActionUrl, setDismissed] = useTalerActionURL()
+  const [talerActionUrl, setDismissed] = useTalerActionURL();
 
   useEffect(() => {
-    if (talerActionUrl) route(Pages.cta)
-  },[talerActionUrl])
+    if (talerActionUrl) route(Pages.cta);
+  }, [talerActionUrl]);
 
   return (
     <div>
@@ -78,33 +76,54 @@ function Application() {
           <Router history={createHashHistory()}>
             <Route path={Pages.dev} component={DeveloperPage} />
 
-            <Route path={Pages.balance} component={BalancePage}
-              goToWalletManualWithdraw={() => 
goToWalletPage(Pages.manual_withdraw)}
+            <Route
+              path={Pages.balance}
+              component={BalancePage}
+              goToWalletManualWithdraw={() =>
+                goToWalletPage(Pages.manual_withdraw)
+              }
             />
             <Route path={Pages.settings} component={SettingsPage} />
-            <Route path={Pages.cta} component={() => <TalerActionFound 
url={talerActionUrl!} onDismiss={() => {
-              setDismissed(true)
-              route(Pages.balance)
-            }} />} />
+            <Route
+              path={Pages.cta}
+              component={() => (
+                <TalerActionFound
+                  url={talerActionUrl!}
+                  onDismiss={() => {
+                    setDismissed(true);
+                    route(Pages.balance);
+                  }}
+                />
+              )}
+            />
 
-            <Route path={Pages.transaction}
-              component={({ tid }: { tid: string }) => 
goToWalletPage(Pages.transaction.replace(':tid', tid))}
+            <Route
+              path={Pages.transaction}
+              component={({ tid }: { tid: string }) =>
+                goToWalletPage(Pages.transaction.replace(":tid", tid))
+              }
             />
 
             <Route path={Pages.history} component={HistoryPage} />
-            <Route path={Pages.backup} component={BackupPage}
+            <Route
+              path={Pages.backup}
+              component={BackupPage}
               onAddProvider={() => {
-                route(Pages.provider_add)
+                route(Pages.provider_add);
               }}
             />
-            <Route path={Pages.provider_detail} component={ProviderDetailPage}
+            <Route
+              path={Pages.provider_detail}
+              component={ProviderDetailPage}
               onBack={() => {
-                route(Pages.backup)
+                route(Pages.backup);
               }}
             />
-            <Route path={Pages.provider_add} component={ProviderAddPage}
+            <Route
+              path={Pages.provider_add}
+              component={ProviderAddPage}
               onBack={() => {
-                route(Pages.backup)
+                route(Pages.backup);
               }}
             />
             <Route default component={Redirect} to={Pages.balance} />
@@ -119,13 +138,13 @@ function goToWalletPage(page: Pages | string): null {
   chrome.tabs.create({
     active: true,
     url: chrome.extension.getURL(`/static/wallet.html#${page}`),
-  })
-  return null
+  });
+  return null;
 }
 
 function Redirect({ to }: { to: string }): null {
   useEffect(() => {
-    route(to, true)
-  })
-  return null
+    route(to, true);
+  });
+  return null;
 }
diff --git a/packages/taler-wallet-webextension/src/renderHtml.tsx 
b/packages/taler-wallet-webextension/src/renderHtml.tsx
index bbe8e465..9c2a794d 100644
--- a/packages/taler-wallet-webextension/src/renderHtml.tsx
+++ b/packages/taler-wallet-webextension/src/renderHtml.tsx
@@ -87,10 +87,7 @@ interface CollapsibleProps {
  * Component that shows/hides its children when clicking
  * a heading.
  */
-export class Collapsible extends Component<
-  CollapsibleProps,
-  CollapsibleState
-> {
+export class Collapsible extends Component<CollapsibleProps, CollapsibleState> 
{
   constructor(props: CollapsibleProps) {
     super(props);
     this.state = { collapsed: props.initiallyCollapsed };
@@ -139,23 +136,20 @@ export function ExpanderText({ text }: 
ExpanderTextProps): JSX.Element {
   return <span>{text}</span>;
 }
 
-export interface LoadingButtonProps extends 
JSX.HTMLAttributes<HTMLButtonElement> {
+export interface LoadingButtonProps
+  extends JSX.HTMLAttributes<HTMLButtonElement> {
   isLoading: boolean;
 }
 
-export function ProgressButton({isLoading, ...rest}: LoadingButtonProps): 
JSX.Element {
+export function ProgressButton({
+  isLoading,
+  ...rest
+}: LoadingButtonProps): JSX.Element {
   return (
-    <button
-      class="pure-button pure-button-primary"
-      type="button"
-      {...rest}
-    >
+    <button class="pure-button pure-button-primary" type="button" {...rest}>
       {isLoading ? (
         <span>
-          <object
-            class="svg-icon svg-baseline"
-            data="/img/spinner-bars.svg"
-          />
+          <object class="svg-icon svg-baseline" data="/img/spinner-bars.svg" />
         </span>
       ) : null}{" "}
       {rest.children}
@@ -163,17 +157,13 @@ export function ProgressButton({isLoading, ...rest}: 
LoadingButtonProps): JSX.El
   );
 }
 
-export function PageLink(
-  props: { pageName: string, children?: ComponentChildren },
-): JSX.Element {
+export function PageLink(props: {
+  pageName: string;
+  children?: ComponentChildren;
+}): JSX.Element {
   const url = 
chrome.extension.getURL(`/static/wallet.html#/${props.pageName}`);
   return (
-    <a
-      class="actionLink"
-      href={url}
-      target="_blank"
-      rel="noopener noreferrer"
-    >
+    <a class="actionLink" href={url} target="_blank" rel="noopener noreferrer">
       {props.children}
     </a>
   );
diff --git a/packages/taler-wallet-webextension/src/test-utils.ts 
b/packages/taler-wallet-webextension/src/test-utils.ts
index 6bf1be3f..28622bb8 100644
--- a/packages/taler-wallet-webextension/src/test-utils.ts
+++ b/packages/taler-wallet-webextension/src/test-utils.ts
@@ -14,15 +14,17 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { ComponentChildren, FunctionalComponent, h as render } from 'preact';
+import { ComponentChildren, FunctionalComponent, h as render } from "preact";
 
-export function createExample<Props>(Component: FunctionalComponent<Props>, 
props: Partial<Props>) {
-  const r = (args: any) => render(Component, args)
-  r.args = props
-  return r
+export function createExample<Props>(
+  Component: FunctionalComponent<Props>,
+  props: Partial<Props>,
+) {
+  const r = (args: any) => render(Component, args);
+  r.args = props;
+  return r;
 }
 
-
 export function NullLink({ children }: { children?: ComponentChildren }) {
-  return render('a', { children, href: 'javascript:void(0);' })
+  return render("a", { children, href: "javascript:void(0);" });
 }
diff --git a/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx
index 9a53fefe..b2771bc2 100644
--- a/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx
@@ -15,179 +15,184 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { ProviderPaymentType } from '@gnu-taler/taler-wallet-core';
-import { addDays } from 'date-fns';
-import { BackupView as TestedComponent } from './BackupPage';
-import { createExample } from '../test-utils';
+import { ProviderPaymentType } from "@gnu-taler/taler-wallet-core";
+import { addDays } from "date-fns";
+import { BackupView as TestedComponent } from "./BackupPage";
+import { createExample } from "../test-utils";
 
 export default {
-  title: 'wallet/backup/list',
+  title: "wallet/backup/list",
   component: TestedComponent,
   argTypes: {
-    onRetry: { action: 'onRetry' },
-    onDelete: { action: 'onDelete' },
-    onBack: { action: 'onBack' },
-  }
+    onRetry: { action: "onRetry" },
+    onDelete: { action: "onDelete" },
+    onBack: { action: "onBack" },
+  },
 };
 
-
 export const LotOfProviders = createExample(TestedComponent, {
-  providers: [{
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
-    },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
-    ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
-    },
-    "terms": {
-      "annualFee": "ARS:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
+  providers: [
+    {
+      active: true,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.taler:9967/";,
+      lastSuccessfulBackupTimestamp: {
+        t_ms: 1625063925078,
+      },
+      paymentProposalIds: [
+        "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
+      ],
+      paymentStatus: {
+        type: ProviderPaymentType.Paid,
+        paidUntil: {
+          t_ms: 1656599921000,
+        },
+      },
+      terms: {
+        annualFee: "ARS:1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
-    ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": addDays(new Date(), 13).getTime()
-      }
+    {
+      active: true,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.taler:9967/";,
+      lastSuccessfulBackupTimestamp: {
+        t_ms: 1625063925078,
+      },
+      paymentProposalIds: [
+        "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
+      ],
+      paymentStatus: {
+        type: ProviderPaymentType.Paid,
+        paidUntil: {
+          t_ms: addDays(new Date(), 13).getTime(),
+        },
+      },
+      terms: {
+        annualFee: "ARS:1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "ARS:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Pending,
+    {
+      active: false,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+      paymentProposalIds: [],
+      paymentStatus: {
+        type: ProviderPaymentType.Pending,
+      },
+      terms: {
+        annualFee: "KUDOS:0.1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "KUDOS:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.InsufficientBalance,
+    {
+      active: false,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+      paymentProposalIds: [],
+      paymentStatus: {
+        type: ProviderPaymentType.InsufficientBalance,
+      },
+      terms: {
+        annualFee: "KUDOS:0.1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "KUDOS:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.TermsChanged,
-      newTerms: {
-        annualFee: 'USD:2',
-        storageLimitInMegabytes: 8,
-        supportedProtocolVersion: '2',
-      },
-      oldTerms: {
-        annualFee: 'USD:1',
+    {
+      active: false,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+      paymentProposalIds: [],
+      paymentStatus: {
+        type: ProviderPaymentType.TermsChanged,
+        newTerms: {
+          annualFee: "USD:2",
+          storageLimitInMegabytes: 8,
+          supportedProtocolVersion: "2",
+        },
+        oldTerms: {
+          annualFee: "USD:1",
+          storageLimitInMegabytes: 16,
+          supportedProtocolVersion: "1",
+        },
+        paidUntil: {
+          t_ms: "never",
+        },
+      },
+      terms: {
+        annualFee: "KUDOS:0.1",
         storageLimitInMegabytes: 16,
-        supportedProtocolVersion: '1',
-
+        supportedProtocolVersion: "0.0",
       },
-      paidUntil: {
-        t_ms: 'never'
-      }
     },
-    "terms": {
-      "annualFee": "KUDOS:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Unpaid,
+    {
+      active: false,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+      paymentProposalIds: [],
+      paymentStatus: {
+        type: ProviderPaymentType.Unpaid,
+      },
+      terms: {
+        annualFee: "KUDOS:0.1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "KUDOS:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }, {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Unpaid,
+    {
+      active: false,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+      paymentProposalIds: [],
+      paymentStatus: {
+        type: ProviderPaymentType.Unpaid,
+      },
+      terms: {
+        annualFee: "KUDOS:0.1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "KUDOS:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }]
+  ],
 });
 
-
 export const OneProvider = createExample(TestedComponent, {
-  providers: [{
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
-    },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
-    ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
+  providers: [
+    {
+      active: true,
+      name: "sync.demo",
+      syncProviderBaseUrl: "http://sync.taler:9967/";,
+      lastSuccessfulBackupTimestamp: {
+        t_ms: 1625063925078,
+      },
+      paymentProposalIds: [
+        "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
+      ],
+      paymentStatus: {
+        type: ProviderPaymentType.Paid,
+        paidUntil: {
+          t_ms: 1656599921000,
+        },
+      },
+      terms: {
+        annualFee: "ARS:1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
     },
-    "terms": {
-      "annualFee": "ARS:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }]
+  ],
 });
 
-
 export const Empty = createExample(TestedComponent, {
-  providers: []
+  providers: [],
 });
-
diff --git a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx 
b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
index 712329bf..c3be0203 100644
--- a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
@@ -14,15 +14,29 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 
-
 import { i18n, Timestamp } from "@gnu-taler/taler-util";
-import { ProviderInfo, ProviderPaymentStatus } from 
"@gnu-taler/taler-wallet-core";
-import { differenceInMonths, formatDuration, intervalToDuration } from 
"date-fns";
+import {
+  ProviderInfo,
+  ProviderPaymentStatus,
+} from "@gnu-taler/taler-wallet-core";
+import {
+  differenceInMonths,
+  formatDuration,
+  intervalToDuration,
+} from "date-fns";
 import { Fragment, JSX, VNode, h } from "preact";
 import {
-  BoldLight, ButtonPrimary, ButtonSuccess, Centered,
-  CenteredText, CenteredBoldText, PopupBox, RowBorderGray,
-  SmallText, SmallLightText, WalletBox
+  BoldLight,
+  ButtonPrimary,
+  ButtonSuccess,
+  Centered,
+  CenteredText,
+  CenteredBoldText,
+  PopupBox,
+  RowBorderGray,
+  SmallText,
+  SmallLightText,
+  WalletBox,
 } from "../components/styled";
 import { useBackupStatus } from "../hooks/useBackupStatus";
 import { Pages } from "../NavigationBar";
@@ -32,49 +46,68 @@ interface Props {
 }
 
 export function BackupPage({ onAddProvider }: Props): VNode {
-  const status = useBackupStatus()
+  const status = useBackupStatus();
   if (!status) {
-    return <div>Loading...</div>
+    return <div>Loading...</div>;
   }
-  return <BackupView providers={status.providers} 
onAddProvider={onAddProvider} onSyncAll={status.sync} />;
+  return (
+    <BackupView
+      providers={status.providers}
+      onAddProvider={onAddProvider}
+      onSyncAll={status.sync}
+    />
+  );
 }
 
 export interface ViewProps {
-  providers: ProviderInfo[],
+  providers: ProviderInfo[];
   onAddProvider: () => void;
   onSyncAll: () => Promise<void>;
 }
 
-export function BackupView({ providers, onAddProvider, onSyncAll }: 
ViewProps): VNode {
+export function BackupView({
+  providers,
+  onAddProvider,
+  onSyncAll,
+}: ViewProps): VNode {
   return (
     <WalletBox>
       <section>
-        {providers.map((provider) => <BackupLayout
-          status={provider.paymentStatus}
-          timestamp={provider.lastSuccessfulBackupTimestamp}
-          id={provider.syncProviderBaseUrl}
-          active={provider.active}
-          title={provider.name}
-        />
+        {providers.map((provider) => (
+          <BackupLayout
+            status={provider.paymentStatus}
+            timestamp={provider.lastSuccessfulBackupTimestamp}
+            id={provider.syncProviderBaseUrl}
+            active={provider.active}
+            title={provider.name}
+          />
+        ))}
+        {!providers.length && (
+          <Centered style={{ marginTop: 100 }}>
+            <BoldLight>No backup providers configured</BoldLight>
+            <ButtonSuccess onClick={onAddProvider}>
+              <i18n.Translate>Add provider</i18n.Translate>
+            </ButtonSuccess>
+          </Centered>
         )}
-        {!providers.length && <Centered style={{ marginTop: 100 }}>
-          <BoldLight>No backup providers configured</BoldLight>
-          <ButtonSuccess onClick={onAddProvider}><i18n.Translate>Add 
provider</i18n.Translate></ButtonSuccess>
-        </Centered>}
       </section>
-      {!!providers.length && <footer>
-        <div />
-        <div>
-          <ButtonPrimary onClick={onSyncAll}>{
-            providers.length > 1 ?
-              <i18n.Translate>Sync all backups</i18n.Translate> :
-              <i18n.Translate>Sync now</i18n.Translate>
-          }</ButtonPrimary>
-          <ButtonSuccess onClick={onAddProvider}>Add provider</ButtonSuccess>
-        </div>
-      </footer>}
+      {!!providers.length && (
+        <footer>
+          <div />
+          <div>
+            <ButtonPrimary onClick={onSyncAll}>
+              {providers.length > 1 ? (
+                <i18n.Translate>Sync all backups</i18n.Translate>
+              ) : (
+                <i18n.Translate>Sync now</i18n.Translate>
+              )}
+            </ButtonPrimary>
+            <ButtonSuccess onClick={onAddProvider}>Add provider</ButtonSuccess>
+          </div>
+        </footer>
+      )}
     </WalletBox>
-  )
+  );
 }
 
 interface TransactionLayoutProps {
@@ -92,55 +125,73 @@ function BackupLayout(props: TransactionLayoutProps): 
JSX.Element {
     timeStyle: "short",
   } as any);
 
-
   return (
     <RowBorderGray>
       <div style={{ color: !props.active ? "grey" : undefined }}>
-        <a href={Pages.provider_detail.replace(':pid', 
encodeURIComponent(props.id))}><span>{props.title}</span></a>
-
-        {dateStr && <SmallText style={{ marginTop: 5 }}>Last synced: 
{dateStr}</SmallText>}
-        {!dateStr && <SmallLightText style={{ marginTop: 5 }}>Not 
synced</SmallLightText>}
+        <a
+          href={Pages.provider_detail.replace(
+            ":pid",
+            encodeURIComponent(props.id),
+          )}
+        >
+          <span>{props.title}</span>
+        </a>
+
+        {dateStr && (
+          <SmallText style={{ marginTop: 5 }}>Last synced: 
{dateStr}</SmallText>
+        )}
+        {!dateStr && (
+          <SmallLightText style={{ marginTop: 5 }}>Not synced</SmallLightText>
+        )}
       </div>
       <div>
-        {props.status?.type === 'paid' ?
-          <ExpirationText until={props.status.paidUntil} /> :
+        {props.status?.type === "paid" ? (
+          <ExpirationText until={props.status.paidUntil} />
+        ) : (
           <div>{props.status.type}</div>
-        }
+        )}
       </div>
     </RowBorderGray>
   );
 }
 
 function ExpirationText({ until }: { until: Timestamp }) {
-  return <Fragment>
-    <CenteredText> Expires in </CenteredText>
-    <CenteredBoldText {...({ color: colorByTimeToExpire(until) })}> 
{daysUntil(until)} </CenteredBoldText>
-  </Fragment>
+  return (
+    <Fragment>
+      <CenteredText> Expires in </CenteredText>
+      <CenteredBoldText {...{ color: colorByTimeToExpire(until) }}>
+        {" "}
+        {daysUntil(until)}{" "}
+      </CenteredBoldText>
+    </Fragment>
+  );
 }
 
 function colorByTimeToExpire(d: Timestamp) {
-  if (d.t_ms === 'never') return 'rgb(28, 184, 65)'
-  const months = differenceInMonths(d.t_ms, new Date())
-  return months > 1 ? 'rgb(28, 184, 65)' : 'rgb(223, 117, 20)';
+  if (d.t_ms === "never") return "rgb(28, 184, 65)";
+  const months = differenceInMonths(d.t_ms, new Date());
+  return months > 1 ? "rgb(28, 184, 65)" : "rgb(223, 117, 20)";
 }
 
 function daysUntil(d: Timestamp) {
-  if (d.t_ms === 'never') return undefined
+  if (d.t_ms === "never") return undefined;
   const duration = intervalToDuration({
     start: d.t_ms,
     end: new Date(),
-  })
+  });
   const str = formatDuration(duration, {
-    delimiter: ', ',
+    delimiter: ", ",
     format: [
-      duration?.years ? 'years' : (
-        duration?.months ? 'months' : (
-          duration?.days ? 'days' : (
-            duration.hours ? 'hours' : 'minutes'
-          )
-        )
-      )
-    ]
-  })
-  return `${str}`
-}
\ No newline at end of file
+      duration?.years
+        ? "years"
+        : duration?.months
+        ? "months"
+        : duration?.days
+        ? "days"
+        : duration.hours
+        ? "hours"
+        : "minutes",
+    ],
+  });
+  return `${str}`;
+}
diff --git a/packages/taler-wallet-webextension/src/wallet/Balance.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/Balance.stories.tsx
index cccda203..2432c31e 100644
--- a/packages/taler-wallet-webextension/src/wallet/Balance.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Balance.stories.tsx
@@ -15,28 +15,25 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample, NullLink } from '../test-utils';
-import { BalanceView as TestedComponent } from './BalancePage';
+import { createExample, NullLink } from "../test-utils";
+import { BalanceView as TestedComponent } from "./BalancePage";
 
 export default {
-  title: 'wallet/balance',
+  title: "wallet/balance",
   component: TestedComponent,
-  argTypes: {
-  }
+  argTypes: {},
 };
 
-
-export const NotYetLoaded = createExample(TestedComponent, {
-});
+export const NotYetLoaded = createExample(TestedComponent, {});
 
 export const GotError = createExample(TestedComponent, {
   balance: {
     hasError: true,
-    message: 'Network error'
+    message: "Network error",
   },
   Linker: NullLink,
 });
@@ -45,7 +42,7 @@ export const EmptyBalance = createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: []
+      balances: [],
     },
   },
   Linker: NullLink,
@@ -55,13 +52,15 @@ export const SomeCoins = createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: [{
-        available: 'USD:10.5',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:0',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      }]
+      balances: [
+        {
+          available: "USD:10.5",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:0",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+      ],
     },
   },
   Linker: NullLink,
@@ -71,13 +70,15 @@ export const SomeCoinsAndIncomingMoney = 
createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: [{
-        available: 'USD:2.23',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:5.11',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      }]
+      balances: [
+        {
+          available: "USD:2.23",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:5.11",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+      ],
     },
   },
   Linker: NullLink,
@@ -87,19 +88,22 @@ export const SomeCoinsInTwoCurrencies = 
createExample(TestedComponent, {
   balance: {
     hasError: false,
     response: {
-      balances: [{
-        available: 'USD:2',
-        hasPendingTransactions: false,
-        pendingIncoming: 'USD:5',
-        pendingOutgoing: 'USD:0',
-        requiresUserInput: false
-      },{
-        available: 'EUR:4',
-        hasPendingTransactions: false,
-        pendingIncoming: 'EUR:5',
-        pendingOutgoing: 'EUR:0',
-        requiresUserInput: false
-      }]
+      balances: [
+        {
+          available: "USD:2",
+          hasPendingTransactions: false,
+          pendingIncoming: "USD:5",
+          pendingOutgoing: "USD:0",
+          requiresUserInput: false,
+        },
+        {
+          available: "EUR:4",
+          hasPendingTransactions: false,
+          pendingIncoming: "EUR:5",
+          pendingOutgoing: "EUR:0",
+          requiresUserInput: false,
+        },
+      ],
     },
   },
   Linker: NullLink,
diff --git a/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx 
b/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx
index eb5a0447..f3c08a3e 100644
--- a/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx
@@ -15,19 +15,30 @@
  */
 
 import {
-  amountFractionalBase, Amounts,
-  Balance, BalancesResponse,
-  i18n
+  amountFractionalBase,
+  Amounts,
+  Balance,
+  BalancesResponse,
+  i18n,
 } from "@gnu-taler/taler-util";
-import { JSX } from "preact";
+import { JSX, h } from "preact";
 import { ButtonPrimary, Centered, WalletBox } from 
"../components/styled/index";
 import { BalancesHook, useBalances } from "../hooks/useBalances";
 import { PageLink, renderAmount } from "../renderHtml";
 
-
-export function BalancePage({ goToWalletManualWithdraw }: { 
goToWalletManualWithdraw: () => void }) {
-  const balance = useBalances()
-  return <BalanceView balance={balance} Linker={PageLink} 
goToWalletManualWithdraw={goToWalletManualWithdraw} />
+export function BalancePage({
+  goToWalletManualWithdraw,
+}: {
+  goToWalletManualWithdraw: () => void;
+}) {
+  const balance = useBalances();
+  return (
+    <BalanceView
+      balance={balance}
+      Linker={PageLink}
+      goToWalletManualWithdraw={goToWalletManualWithdraw}
+    />
+  );
 }
 
 export interface BalanceViewProps {
@@ -36,9 +47,13 @@ export interface BalanceViewProps {
   goToWalletManualWithdraw: () => void;
 }
 
-export function BalanceView({ balance, Linker, goToWalletManualWithdraw }: 
BalanceViewProps) {
+export function BalanceView({
+  balance,
+  Linker,
+  goToWalletManualWithdraw,
+}: BalanceViewProps) {
   if (!balance) {
-    return <span />
+    return <span />;
   }
 
   if (balance.hasError) {
@@ -50,19 +65,24 @@ export function BalanceView({ balance, Linker, 
goToWalletManualWithdraw }: Balan
           diagnostics.
         </p>
       </div>
-    )
+    );
   }
   if (balance.response.balances.length === 0) {
     return (
-      <p><i18n.Translate>
-        You have no balance to show. Need some{" "}
-        <Linker pageName="/welcome">help</Linker> getting started?
-      </i18n.Translate></p>
-    )
+      <p>
+        <i18n.Translate>
+          You have no balance to show. Need some{" "}
+          <Linker pageName="/welcome">help</Linker> getting started?
+        </i18n.Translate>
+      </p>
+    );
   }
-  return <ShowBalances wallet={balance.response}
-    onWithdraw={goToWalletManualWithdraw}
-  />
+  return (
+    <ShowBalances
+      wallet={balance.response}
+      onWithdraw={goToWalletManualWithdraw}
+    />
+  );
 }
 
 function formatPending(entry: Balance): JSX.Element {
@@ -75,13 +95,15 @@ function formatPending(entry: Balance): JSX.Element {
 
   if (!Amounts.isZero(pendingIncoming)) {
     incoming = (
-      <span><i18n.Translate>
-        <span style={{ color: "darkgreen" }}>
-          {"+"}
-          {renderAmount(entry.pendingIncoming)}
-        </span>{" "}
-        incoming
-      </i18n.Translate></span>
+      <span>
+        <i18n.Translate>
+          <span style={{ color: "darkgreen" }}>
+            {"+"}
+            {renderAmount(entry.pendingIncoming)}
+          </span>{" "}
+          incoming
+        </i18n.Translate>
+      </span>
     );
   }
 
@@ -100,27 +122,36 @@ function formatPending(entry: Balance): JSX.Element {
   );
 }
 
-
-function ShowBalances({ wallet, onWithdraw }: { wallet: BalancesResponse, 
onWithdraw: () => void }) {
-  return <WalletBox>
-    <section>
-      <Centered>{wallet.balances.map((entry) => {
-        const av = Amounts.parseOrThrow(entry.available);
-        const v = av.value + av.fraction / amountFractionalBase;
-        return (
-          <p key={av.currency}>
-            <span>
-              <span style={{ fontSize: "5em", display: "block" }}>{v}</span>{" 
"}
-              <span>{av.currency}</span>
-            </span>
-            {formatPending(entry)}
-          </p>
-        );
-      })}</Centered>
-    </section>
-    <footer>
-      <div />
-      <ButtonPrimary onClick={onWithdraw} >Withdraw</ButtonPrimary>
-    </footer>
-  </WalletBox>
+function ShowBalances({
+  wallet,
+  onWithdraw,
+}: {
+  wallet: BalancesResponse;
+  onWithdraw: () => void;
+}) {
+  return (
+    <WalletBox>
+      <section>
+        <Centered>
+          {wallet.balances.map((entry) => {
+            const av = Amounts.parseOrThrow(entry.available);
+            const v = av.value + av.fraction / amountFractionalBase;
+            return (
+              <p key={av.currency}>
+                <span>
+                  <span style={{ fontSize: "5em", display: "block" 
}}>{v}</span>{" "}
+                  <span>{av.currency}</span>
+                </span>
+                {formatPending(entry)}
+              </p>
+            );
+          })}
+        </Centered>
+      </section>
+      <footer>
+        <div />
+        <ButtonPrimary onClick={onWithdraw}>Withdraw</ButtonPrimary>
+      </footer>
+    </WalletBox>
+  );
 }
diff --git 
a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.stories.tsx
 
b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.stories.tsx
index 35da5239..6eab8dc3 100644
--- 
a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.stories.tsx
+++ 
b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.stories.tsx
@@ -15,42 +15,39 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample } from '../test-utils';
-import { CreateManualWithdraw as TestedComponent } from 
'./CreateManualWithdraw';
+import { createExample } from "../test-utils";
+import { CreateManualWithdraw as TestedComponent } from 
"./CreateManualWithdraw";
 
 export default {
-  title: 'wallet/manual withdraw/creation',
+  title: "wallet/manual withdraw/creation",
   component: TestedComponent,
-  argTypes: {
-  }
+  argTypes: {},
 };
 
-
-export const InitialState = createExample(TestedComponent, {
-});
+export const InitialState = createExample(TestedComponent, {});
 
 export const WithExchangeFilled = createExample(TestedComponent, {
-  currency: 'COL',
-  initialExchange: 'http://exchange.taler:8081',
+  currency: "COL",
+  initialExchange: "http://exchange.taler:8081";,
 });
 
 export const WithExchangeAndAmountFilled = createExample(TestedComponent, {
-  currency: 'COL',
-  initialExchange: 'http://exchange.taler:8081',
-  initialAmount: '10'
+  currency: "COL",
+  initialExchange: "http://exchange.taler:8081";,
+  initialAmount: "10",
 });
 
 export const WithExchangeError = createExample(TestedComponent, {
-  initialExchange: 'http://exchange.tal',
-  error: 'The exchange url seems invalid'
+  initialExchange: "http://exchange.tal";,
+  error: "The exchange url seems invalid",
 });
 
 export const WithAmountError = createExample(TestedComponent, {
-  currency: 'COL',
-  initialExchange: 'http://exchange.taler:8081',
-  initialAmount: 'e'
+  currency: "COL",
+  initialExchange: "http://exchange.taler:8081";,
+  initialAmount: "e",
 });
diff --git 
a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx 
b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx
index be2cbe41..b48dcbaf 100644
--- a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx
@@ -1,8 +1,35 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
 import { AmountJson, Amounts } from "@gnu-taler/taler-util";
-import { VNode } from "preact";
+import { VNode, h } from "preact";
 import { useEffect, useRef, useState } from "preact/hooks";
 import { ErrorMessage } from "../components/ErrorMessage";
-import { ButtonPrimary, Input, InputWithLabel, LightText, WalletBox } from 
"../components/styled";
+import {
+  ButtonPrimary,
+  Input,
+  InputWithLabel,
+  LightText,
+  WalletBox,
+} from "../components/styled";
 
 export interface Props {
   error: string | undefined;
@@ -13,44 +40,73 @@ export interface Props {
   onCreate: (exchangeBaseUrl: string, amount: AmountJson) => Promise<void>;
 }
 
-export function CreateManualWithdraw({ onExchangeChange, initialExchange, 
initialAmount, error, currency, onCreate }: Props): VNode {
+export function CreateManualWithdraw({
+  onExchangeChange,
+  initialExchange,
+  initialAmount,
+  error,
+  currency,
+  onCreate,
+}: Props): VNode {
   const [exchange, setExchange] = useState(initialExchange || "");
   const [amount, setAmount] = useState(initialAmount || "");
-  const parsedAmount = Amounts.parse(`${currency}:${amount}`)
+  const parsedAmount = Amounts.parse(`${currency}:${amount}`);
 
   let timeout = useRef<number | undefined>(undefined);
   useEffect(() => {
-    if (timeout) window.clearTimeout(timeout.current)
+    if (timeout) window.clearTimeout(timeout.current);
     timeout.current = window.setTimeout(async () => {
-      onExchangeChange(exchange)
+      onExchangeChange(exchange);
     }, 1000);
-  }, [exchange])
-
+  }, [exchange]);
 
   return (
     <WalletBox>
       <section>
-        <ErrorMessage title={error && "Can't create the reserve"} 
description={error} />
+        <ErrorMessage
+          title={error && "Can't create the reserve"}
+          description={error}
+        />
         <h2>Manual Withdrawal</h2>
-        <LightText>Choose a exchange to create a reserve and then fill the 
reserve to withdraw the coins</LightText>
+        <LightText>
+          Choose a exchange to create a reserve and then fill the reserve to
+          withdraw the coins
+        </LightText>
         <p>
           <Input invalid={!!exchange && !currency}>
             <label>Exchange</label>
-            <input type="text" placeholder="https://"; value={exchange} 
onChange={(e) => setExchange(e.currentTarget.value)} />
+            <input
+              type="text"
+              placeholder="https://";
+              value={exchange}
+              onChange={(e) => setExchange(e.currentTarget.value)}
+            />
             <small>http://exchange.taler:8081</small>
           </Input>
-          {currency && <InputWithLabel invalid={!!amount && !parsedAmount}>
-            <label>Amount</label>
-            <div>
-              <div>{currency}</div>
-              <input type="number" style={{ paddingLeft: 
`${currency.length}em` }} value={amount} onChange={e => 
setAmount(e.currentTarget.value)} />
-            </div>
-          </InputWithLabel>}
+          {currency && (
+            <InputWithLabel invalid={!!amount && !parsedAmount}>
+              <label>Amount</label>
+              <div>
+                <div>{currency}</div>
+                <input
+                  type="number"
+                  style={{ paddingLeft: `${currency.length}em` }}
+                  value={amount}
+                  onChange={(e) => setAmount(e.currentTarget.value)}
+                />
+              </div>
+            </InputWithLabel>
+          )}
         </p>
       </section>
       <footer>
         <div />
-        <ButtonPrimary disabled={!parsedAmount || !exchange} onClick={() => 
onCreate(exchange, parsedAmount!)}>Create</ButtonPrimary>
+        <ButtonPrimary
+          disabled={!parsedAmount || !exchange}
+          onClick={() => onCreate(exchange, parsedAmount!)}
+        >
+          Create
+        </ButtonPrimary>
       </footer>
     </WalletBox>
   );
diff --git a/packages/taler-wallet-webextension/src/wallet/History.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx
index 0ac4be9a..9ae3ac3b 100644
--- a/packages/taler-wallet-webextension/src/wallet/History.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx
@@ -15,133 +15,146 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
 import {
   PaymentStatus,
-  TransactionCommon, TransactionDeposit, TransactionPayment,
-  TransactionRefresh, TransactionRefund, TransactionTip, TransactionType,
+  TransactionCommon,
+  TransactionDeposit,
+  TransactionPayment,
+  TransactionRefresh,
+  TransactionRefund,
+  TransactionTip,
+  TransactionType,
   TransactionWithdrawal,
-  WithdrawalType
-} from '@gnu-taler/taler-util';
-import { HistoryView as TestedComponent } from './History';
-import { createExample } from '../test-utils';
-
+  WithdrawalType,
+} from "@gnu-taler/taler-util";
+import { HistoryView as TestedComponent } from "./History";
+import { createExample } from "../test-utils";
 
 export default {
-  title: 'wallet/history/list',
+  title: "wallet/history/list",
   component: TestedComponent,
 };
 
-let count = 0
-const commonTransaction = () => ({
-  amountRaw: 'USD:10',
-  amountEffective: 'USD:9',
-  pending: false,
-  timestamp: {
-    t_ms: new Date().getTime() - (count++ * 1000 * 60 * 60 * 7)
-  },
-  transactionId: '12',
-} as TransactionCommon)
+let count = 0;
+const commonTransaction = () =>
+  ({
+    amountRaw: "USD:10",
+    amountEffective: "USD:9",
+    pending: false,
+    timestamp: {
+      t_ms: new Date().getTime() - count++ * 1000 * 60 * 60 * 7,
+    },
+    transactionId: "12",
+  } as TransactionCommon);
 
 const exampleData = {
   withdraw: {
     ...commonTransaction(),
     type: TransactionType.Withdrawal,
-    exchangeBaseUrl: 'http://exchange.demo.taler.net',
+    exchangeBaseUrl: "http://exchange.demo.taler.net";,
     withdrawalDetails: {
       confirmed: false,
-      exchangePaytoUris: ['payto://x-taler-bank/bank/account'],
+      exchangePaytoUris: ["payto://x-taler-bank/bank/account"],
       type: WithdrawalType.ManualTransfer,
-    }
+    },
   } as TransactionWithdrawal,
   payment: {
     ...commonTransaction(),
-    amountEffective: 'USD:11',
+    amountEffective: "USD:11",
     type: TransactionType.Payment,
     info: {
-      contractTermsHash: 'ASDZXCASD',
+      contractTermsHash: "ASDZXCASD",
       merchant: {
-        name: 'Blog',
+        name: "Blog",
       },
-      orderId: '2021.167-03NPY6MCYMVGT',
+      orderId: "2021.167-03NPY6MCYMVGT",
       products: [],
-      summary: 'the summary',
-      fulfillmentMessage: '',
+      summary: "the summary",
+      fulfillmentMessage: "",
     },
-    proposalId: '1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0',
+    proposalId: "1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
     status: PaymentStatus.Accepted,
   } as TransactionPayment,
   deposit: {
     ...commonTransaction(),
     type: TransactionType.Deposit,
-    depositGroupId: '#groupId',
-    targetPaytoUri: 'payto://x-taler-bank/bank/account',
+    depositGroupId: "#groupId",
+    targetPaytoUri: "payto://x-taler-bank/bank/account",
   } as TransactionDeposit,
   refresh: {
     ...commonTransaction(),
     type: TransactionType.Refresh,
-    exchangeBaseUrl: 'http://exchange.taler',
+    exchangeBaseUrl: "http://exchange.taler";,
   } as TransactionRefresh,
   tip: {
     ...commonTransaction(),
     type: TransactionType.Tip,
-    merchantBaseUrl: 'http://ads.merchant.taler.net/',
+    merchantBaseUrl: "http://ads.merchant.taler.net/";,
   } as TransactionTip,
   refund: {
     ...commonTransaction(),
     type: TransactionType.Refund,
-    refundedTransactionId: 
'payment:1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0',
+    refundedTransactionId:
+      "payment:1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
     info: {
-      contractTermsHash: 'ASDZXCASD',
+      contractTermsHash: "ASDZXCASD",
       merchant: {
-        name: 'the merchant',
+        name: "the merchant",
       },
-      orderId: '2021.167-03NPY6MCYMVGT',
+      orderId: "2021.167-03NPY6MCYMVGT",
       products: [],
-      summary: 'the summary',
-      fulfillmentMessage: '',
+      summary: "the summary",
+      fulfillmentMessage: "",
     },
   } as TransactionRefund,
-}
+};
 
 export const Empty = createExample(TestedComponent, {
   list: [],
-  balances: [{
-    available: 'TESTKUDOS:10',
-    pendingIncoming: 'TESTKUDOS:0',
-    pendingOutgoing: 'TESTKUDOS:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }]
+  balances: [
+    {
+      available: "TESTKUDOS:10",
+      pendingIncoming: "TESTKUDOS:0",
+      pendingOutgoing: "TESTKUDOS:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+  ],
 });
 
-
 export const One = createExample(TestedComponent, {
   list: [exampleData.withdraw],
-  balances: [{
-    available: 'USD:10',
-    pendingIncoming: 'USD:0',
-    pendingOutgoing: 'USD:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }]
+  balances: [
+    {
+      available: "USD:10",
+      pendingIncoming: "USD:0",
+      pendingOutgoing: "USD:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+  ],
 });
 
 export const OnePending = createExample(TestedComponent, {
-  list: [{
-    ...exampleData.withdraw,
-    pending: true
-  }],
-  balances: [{
-    available: 'USD:10',
-    pendingIncoming: 'USD:0',
-    pendingOutgoing: 'USD:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }]
+  list: [
+    {
+      ...exampleData.withdraw,
+      pending: true,
+    },
+  ],
+  balances: [
+    {
+      available: "USD:10",
+      pendingIncoming: "USD:0",
+      pendingOutgoing: "USD:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+  ],
 });
 
 export const Several = createExample(TestedComponent, {
@@ -154,20 +167,23 @@ export const Several = createExample(TestedComponent, {
       ...exampleData.payment,
       info: {
         ...exampleData.payment.info,
-        summary: 'this is a long summary that may be cropped because its too 
long',
+        summary:
+          "this is a long summary that may be cropped because its too long",
       },
     },
     exampleData.refund,
     exampleData.tip,
     exampleData.deposit,
   ],
-  balances: [{
-    available: 'TESTKUDOS:10',
-    pendingIncoming: 'TESTKUDOS:0',
-    pendingOutgoing: 'TESTKUDOS:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }]
+  balances: [
+    {
+      available: "TESTKUDOS:10",
+      pendingIncoming: "TESTKUDOS:0",
+      pendingOutgoing: "TESTKUDOS:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+  ],
 });
 
 export const SeveralWithTwoCurrencies = createExample(TestedComponent, {
@@ -181,18 +197,20 @@ export const SeveralWithTwoCurrencies = 
createExample(TestedComponent, {
     exampleData.tip,
     exampleData.deposit,
   ],
-  balances: [{
-    available: 'TESTKUDOS:10',
-    pendingIncoming: 'TESTKUDOS:0',
-    pendingOutgoing: 'TESTKUDOS:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }, {
-    available: 'USD:10',
-    pendingIncoming: 'USD:0',
-    pendingOutgoing: 'USD:0',
-    hasPendingTransactions: false,
-    requiresUserInput: false,
-  }]
+  balances: [
+    {
+      available: "TESTKUDOS:10",
+      pendingIncoming: "TESTKUDOS:0",
+      pendingOutgoing: "TESTKUDOS:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+    {
+      available: "USD:10",
+      pendingIncoming: "USD:0",
+      pendingOutgoing: "USD:0",
+      hasPendingTransactions: false,
+      requiresUserInput: false,
+    },
+  ],
 });
-
diff --git a/packages/taler-wallet-webextension/src/wallet/History.tsx 
b/packages/taler-wallet-webextension/src/wallet/History.tsx
index 8160f857..aabe50a2 100644
--- a/packages/taler-wallet-webextension/src/wallet/History.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/History.tsx
@@ -14,7 +14,12 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { AmountString, Balance, Transaction, TransactionsResponse } from 
"@gnu-taler/taler-util";
+import {
+  AmountString,
+  Balance,
+  Transaction,
+  TransactionsResponse,
+} from "@gnu-taler/taler-util";
 import { format } from "date-fns";
 import { Fragment, h, JSX } from "preact";
 import { useEffect, useState } from "preact/hooks";
@@ -23,13 +28,14 @@ import { TransactionItem } from 
"../components/TransactionItem";
 import { useBalances } from "../hooks/useBalances";
 import * as wxApi from "../wxApi";
 
-
 export function HistoryPage(props: any): JSX.Element {
   const [transactions, setTransactions] = useState<
     TransactionsResponse | undefined
   >(undefined);
-  const balance = useBalances()
-  const balanceWithoutError = balance?.hasError ? [] : 
(balance?.response.balances || [])
+  const balance = useBalances();
+  const balanceWithoutError = balance?.hasError
+    ? []
+    : balance?.response.balances || [];
 
   useEffect(() => {
     const fetchData = async (): Promise<void> => {
@@ -43,45 +49,74 @@ export function HistoryPage(props: any): JSX.Element {
     return <div>Loading ...</div>;
   }
 
-  return <HistoryView balances={balanceWithoutError} 
list={[...transactions.transactions].reverse()} />;
+  return (
+    <HistoryView
+      balances={balanceWithoutError}
+      list={[...transactions.transactions].reverse()}
+    />
+  );
 }
 
 function amountToString(c: AmountString) {
-  const idx = c.indexOf(':')
-  return `${c.substring(idx + 1)} ${c.substring(0, idx)}`
+  const idx = c.indexOf(":");
+  return `${c.substring(idx + 1)} ${c.substring(0, idx)}`;
 }
 
-
-
-export function HistoryView({ list, balances }: { list: Transaction[], 
balances: Balance[] }) {
+export function HistoryView({
+  list,
+  balances,
+}: {
+  list: Transaction[];
+  balances: Balance[];
+}) {
   const byDate = list.reduce(function (rv, x) {
-    const theDate = x.timestamp.t_ms === "never" ? "never" : 
format(x.timestamp.t_ms, 'dd MMMM yyyy');
+    const theDate =
+      x.timestamp.t_ms === "never"
+        ? "never"
+        : format(x.timestamp.t_ms, "dd MMMM yyyy");
     (rv[theDate] = rv[theDate] || []).push(x);
     return rv;
   }, {} as { [x: string]: Transaction[] });
 
-  const multiCurrency = balances.length > 1
+  const multiCurrency = balances.length > 1;
 
-  return <WalletBox noPadding>
-    {balances.length > 0 && <header>
-      {balances.length === 1 && <div class="title">
-        Balance: <span>{amountToString(balances[0].available)}</span>
-      </div>}
-      {balances.length > 1 && <div class="title">
-        Balance: <ul style={{ margin: 0 }}>
-          {balances.map(b => <li>{b.available}</li>)}
-        </ul>
-      </div>}
-    </header>}
-    <section>
-      {Object.keys(byDate).map((d,i) => {
-        return <Fragment key={i}>
-          <DateSeparator>{d}</DateSeparator>
-          {byDate[d].map((tx, i) => (
-            <TransactionItem key={i} tx={tx} multiCurrency={multiCurrency}/>
-          ))}
-        </Fragment>
-      })}
-    </section>
-  </WalletBox>
+  return (
+    <WalletBox noPadding>
+      {balances.length > 0 && (
+        <header>
+          {balances.length === 1 && (
+            <div class="title">
+              Balance: <span>{amountToString(balances[0].available)}</span>
+            </div>
+          )}
+          {balances.length > 1 && (
+            <div class="title">
+              Balance:{" "}
+              <ul style={{ margin: 0 }}>
+                {balances.map((b) => (
+                  <li>{b.available}</li>
+                ))}
+              </ul>
+            </div>
+          )}
+        </header>
+      )}
+      <section>
+        {Object.keys(byDate).map((d, i) => {
+          return (
+            <Fragment key={i}>
+              <DateSeparator>{d}</DateSeparator>
+              {byDate[d].map((tx, i) => (
+                <TransactionItem
+                  key={i}
+                  tx={tx}
+                  multiCurrency={multiCurrency}
+                />
+              ))}
+            </Fragment>
+          );
+        })}
+      </section>
+    </WalletBox>
+  );
 }
diff --git 
a/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx 
b/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx
index dcc0002e..102978f9 100644
--- a/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx
@@ -14,68 +14,84 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 
-
-import { VNode } from "preact";
-import { useEffect, useRef, useState } from "preact/hooks";
+import { VNode, h } from "preact";
+import { useState } from "preact/hooks";
 import { CreateManualWithdraw } from "./CreateManualWithdraw";
-import * as wxApi from '../wxApi'
-import { AcceptManualWithdrawalResult, AmountJson, Amounts } from 
"@gnu-taler/taler-util";
+import * as wxApi from "../wxApi";
+import {
+  AcceptManualWithdrawalResult,
+  AmountJson,
+  Amounts,
+} from "@gnu-taler/taler-util";
 import { ReserveCreated } from "./ReserveCreated.js";
-import { route } from 'preact-router';
+import { route } from "preact-router";
 import { Pages } from "../NavigationBar.js";
 
-interface Props {
-
-}
+interface Props {}
 
-export function ManualWithdrawPage({ }: Props): VNode {
-  const [success, setSuccess] = useState<AcceptManualWithdrawalResult | 
undefined>(undefined)
-  const [currency, setCurrency] = useState<string | undefined>(undefined)
-  const [error, setError] = useState<string | undefined>(undefined)
+export function ManualWithdrawPage({}: Props): VNode {
+  const [success, setSuccess] = useState<
+    AcceptManualWithdrawalResult | undefined
+  >(undefined);
+  const [currency, setCurrency] = useState<string | undefined>(undefined);
+  const [error, setError] = useState<string | undefined>(undefined);
 
-  async function onExchangeChange(exchange: string | undefined) {
-    if (!exchange) return
+  async function onExchangeChange(exchange: string | undefined): Promise<void> 
{
+    if (!exchange) return;
     try {
-      const r = await fetch(`${exchange}/keys`)
-      const j = await r.json()
+      const r = await fetch(`${exchange}/keys`);
+      const j = await r.json();
       if (j.currency) {
         await wxApi.addExchange({
           exchangeBaseUrl: `${exchange}/`,
-          forceUpdate: true
-        })
-        setCurrency(j.currency)
+          forceUpdate: true,
+        });
+        setCurrency(j.currency);
       }
     } catch (e) {
-      setError('The exchange url seems invalid')
-      setCurrency(undefined)
+      setError("The exchange url seems invalid");
+      setCurrency(undefined);
     }
   }
 
-  async function doCreate(exchangeBaseUrl: string, amount: AmountJson) {
+  async function doCreate(
+    exchangeBaseUrl: string,
+    amount: AmountJson,
+  ): Promise<void> {
     try {
-      const resp = await wxApi.acceptManualWithdrawal(exchangeBaseUrl, 
Amounts.stringify(amount))
-      setSuccess(resp)
+      const resp = await wxApi.acceptManualWithdrawal(
+        exchangeBaseUrl,
+        Amounts.stringify(amount),
+      );
+      setSuccess(resp);
     } catch (e) {
       if (e instanceof Error) {
-        setError(e.message)
+        setError(e.message);
       } else {
-        setError('unexpected error')
+        setError("unexpected error");
       }
-      setSuccess(undefined)
+      setSuccess(undefined);
     }
   }
 
   if (success) {
-    return <ReserveCreated reservePub={success.reservePub} 
paytos={success.exchangePaytoUris} onBack={() => {
-      route(Pages.balance)
-    }}/>
+    return (
+      <ReserveCreated
+        reservePub={success.reservePub}
+        paytos={success.exchangePaytoUris}
+        onBack={() => {
+          route(Pages.balance);
+        }}
+      />
+    );
   }
 
-  return <CreateManualWithdraw
-    error={error} currency={currency}
-    onCreate={doCreate} onExchangeChange={onExchangeChange}
-  />;
+  return (
+    <CreateManualWithdraw
+      error={error}
+      currency={currency}
+      onCreate={doCreate}
+      onExchangeChange={onExchangeChange}
+    />
+  );
 }
-
-
-
diff --git 
a/packages/taler-wallet-webextension/src/wallet/ProviderAddConfirmProvider.stories.tsx
 
b/packages/taler-wallet-webextension/src/wallet/ProviderAddConfirmProvider.stories.tsx
index d1e76c05..5c4e56b1 100644
--- 
a/packages/taler-wallet-webextension/src/wallet/ProviderAddConfirmProvider.stories.tsx
+++ 
b/packages/taler-wallet-webextension/src/wallet/ProviderAddConfirmProvider.stories.tsx
@@ -15,38 +15,37 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample } from '../test-utils';
-import { ConfirmProviderView as TestedComponent } from './ProviderAddPage';
+import { createExample } from "../test-utils";
+import { ConfirmProviderView as TestedComponent } from "./ProviderAddPage";
 
 export default {
-  title: 'wallet/backup/confirm',
+  title: "wallet/backup/confirm",
   component: TestedComponent,
   argTypes: {
-    onRetry: { action: 'onRetry' },
-    onDelete: { action: 'onDelete' },
-    onBack: { action: 'onBack' },
-  }
+    onRetry: { action: "onRetry" },
+    onDelete: { action: "onDelete" },
+    onBack: { action: "onBack" },
+  },
 };
 
-
 export const DemoService = createExample(TestedComponent, {
-  url: 'https://sync.demo.taler.net/',
+  url: "https://sync.demo.taler.net/";,
   provider: {
-    annual_fee: 'KUDOS:0.1',
-    storage_limit_in_megabytes: 20, 
-    supported_protocol_version: '1'
-  }
+    annual_fee: "KUDOS:0.1",
+    storage_limit_in_megabytes: 20,
+    supported_protocol_version: "1",
+  },
 });
 
 export const FreeService = createExample(TestedComponent, {
-  url: 'https://sync.taler:9667/',
+  url: "https://sync.taler:9667/";,
   provider: {
-    annual_fee: 'ARS:0',
-    storage_limit_in_megabytes: 20, 
-    supported_protocol_version: '1'
-  }
+    annual_fee: "ARS:0",
+    storage_limit_in_megabytes: 20,
+    supported_protocol_version: "1",
+  },
 });
diff --git 
a/packages/taler-wallet-webextension/src/wallet/ProviderAddSetUrl.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/ProviderAddSetUrl.stories.tsx
index 4890e5e9..75292b7e 100644
--- 
a/packages/taler-wallet-webextension/src/wallet/ProviderAddSetUrl.stories.tsx
+++ 
b/packages/taler-wallet-webextension/src/wallet/ProviderAddSetUrl.stories.tsx
@@ -15,39 +15,37 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample } from '../test-utils';
-import { SetUrlView as TestedComponent } from './ProviderAddPage';
+import { createExample } from "../test-utils";
+import { SetUrlView as TestedComponent } from "./ProviderAddPage";
 
 export default {
-  title: 'wallet/backup/add',
+  title: "wallet/backup/add",
   component: TestedComponent,
   argTypes: {
-    onRetry: { action: 'onRetry' },
-    onDelete: { action: 'onDelete' },
-    onBack: { action: 'onBack' },
-  }
+    onRetry: { action: "onRetry" },
+    onDelete: { action: "onDelete" },
+    onBack: { action: "onBack" },
+  },
 };
 
-
-export const Initial = createExample(TestedComponent, {
-}); 
+export const Initial = createExample(TestedComponent, {});
 
 export const WithValue = createExample(TestedComponent, {
-  initialValue: 'sync.demo.taler.net'
-}); 
+  initialValue: "sync.demo.taler.net",
+});
 
 export const WithConnectionError = createExample(TestedComponent, {
-  withError: 'Network error'
-}); 
+  withError: "Network error",
+});
 
 export const WithClientError = createExample(TestedComponent, {
-  withError: 'URL may not be right: (404) Not Found'
-}); 
+  withError: "URL may not be right: (404) Not Found",
+});
 
 export const WithServerError = createExample(TestedComponent, {
-  withError: 'Try another server: (500) Internal Server Error'
-}); 
+  withError: "Try another server: (500) Internal Server Error",
+});
diff --git 
a/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx
index 67ff8344..a170620a 100644
--- a/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx
@@ -15,224 +15,221 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { ProviderPaymentType } from '@gnu-taler/taler-wallet-core';
-import { createExample } from '../test-utils';
-import { ProviderView as TestedComponent } from './ProviderDetailPage';
+import { ProviderPaymentType } from "@gnu-taler/taler-wallet-core";
+import { createExample } from "../test-utils";
+import { ProviderView as TestedComponent } from "./ProviderDetailPage";
 
 export default {
-  title: 'wallet/backup/details',
+  title: "wallet/backup/details",
   component: TestedComponent,
   argTypes: {
-    onRetry: { action: 'onRetry' },
-    onDelete: { action: 'onDelete' },
-    onBack: { action: 'onBack' },
-  }
+    onRetry: { action: "onRetry" },
+    onDelete: { action: "onDelete" },
+    onBack: { action: "onBack" },
+  },
 };
 
-
 export const Active = createExample(TestedComponent, {
   info: {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
-    },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
+    active: true,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.taler:9967/";,
+    lastSuccessfulBackupTimestamp: {
+      t_ms: 1625063925078,
+    },
+    paymentProposalIds: [
+      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
     ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
-    },
-    "terms": {
-      "annualFee": "EUR:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+    paymentStatus: {
+      type: ProviderPaymentType.Paid,
+      paidUntil: {
+        t_ms: 1656599921000,
+      },
+    },
+    terms: {
+      annualFee: "EUR:1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const ActiveErrorSync = createExample(TestedComponent, {
   info: {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
+    active: true,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.taler:9967/";,
+    lastSuccessfulBackupTimestamp: {
+      t_ms: 1625063925078,
     },
     lastAttemptedBackupTimestamp: {
-      "t_ms": 1625063925078
+      t_ms: 1625063925078,
     },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
+    paymentProposalIds: [
+      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
     ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
+    paymentStatus: {
+      type: ProviderPaymentType.Paid,
+      paidUntil: {
+        t_ms: 1656599921000,
+      },
     },
     lastError: {
       code: 2002,
-      details: 'details',
-      hint: 'error hint from the server',
-      message: 'message'
-    },
-    "terms": {
-      "annualFee": "EUR:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+      details: "details",
+      hint: "error hint from the server",
+      message: "message",
+    },
+    terms: {
+      annualFee: "EUR:1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const ActiveBackupProblemUnreadable = createExample(TestedComponent, {
   info: {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
-    },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
+    active: true,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.taler:9967/";,
+    lastSuccessfulBackupTimestamp: {
+      t_ms: 1625063925078,
+    },
+    paymentProposalIds: [
+      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
     ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
+    paymentStatus: {
+      type: ProviderPaymentType.Paid,
+      paidUntil: {
+        t_ms: 1656599921000,
+      },
     },
     backupProblem: {
-      type: 'backup-unreadable'
-    },
-    "terms": {
-      "annualFee": "EUR:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+      type: "backup-unreadable",
+    },
+    terms: {
+      annualFee: "EUR:1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const ActiveBackupProblemDevice = createExample(TestedComponent, {
   info: {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.taler:9967/";,
-    "lastSuccessfulBackupTimestamp": {
-      "t_ms": 1625063925078
-    },
-    "paymentProposalIds": [
-      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
+    active: true,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.taler:9967/";,
+    lastSuccessfulBackupTimestamp: {
+      t_ms: 1625063925078,
+    },
+    paymentProposalIds: [
+      "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG",
     ],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Paid,
-      "paidUntil": {
-        "t_ms": 1656599921000
-      }
+    paymentStatus: {
+      type: ProviderPaymentType.Paid,
+      paidUntil: {
+        t_ms: 1656599921000,
+      },
     },
     backupProblem: {
-      type: 'backup-conflicting-device',
-      myDeviceId: 'my-device-id',
-      otherDeviceId: 'other-device-id',
+      type: "backup-conflicting-device",
+      myDeviceId: "my-device-id",
+      otherDeviceId: "other-device-id",
       backupTimestamp: {
-        "t_ms": 1656599921000
-      }
-    },
-    "terms": {
-      "annualFee": "EUR:1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+        t_ms: 1656599921000,
+      },
+    },
+    terms: {
+      annualFee: "EUR:1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const InactiveUnpaid = createExample(TestedComponent, {
   info: {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Unpaid,
-    },
-    "terms": {
-      "annualFee": "EUR:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+    active: false,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+    paymentProposalIds: [],
+    paymentStatus: {
+      type: ProviderPaymentType.Unpaid,
+    },
+    terms: {
+      annualFee: "EUR:0.1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const InactiveInsufficientBalance = createExample(TestedComponent, {
   info: {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.InsufficientBalance,
-    },
-    "terms": {
-      "annualFee": "EUR:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+    active: false,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+    paymentProposalIds: [],
+    paymentStatus: {
+      type: ProviderPaymentType.InsufficientBalance,
+    },
+    terms: {
+      annualFee: "EUR:0.1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
 export const InactivePending = createExample(TestedComponent, {
   info: {
-    "active": false,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.Pending,
-    },
-    "terms": {
-      "annualFee": "EUR:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+    active: false,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+    paymentProposalIds: [],
+    paymentStatus: {
+      type: ProviderPaymentType.Pending,
+    },
+    terms: {
+      annualFee: "EUR:0.1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
 
-
 export const ActiveTermsChanged = createExample(TestedComponent, {
   info: {
-    "active": true,
-    name:'sync.demo',
-    "syncProviderBaseUrl": "http://sync.demo.taler.net/";,
-    "paymentProposalIds": [],
-    "paymentStatus": {
-      "type": ProviderPaymentType.TermsChanged,
+    active: true,
+    name: "sync.demo",
+    syncProviderBaseUrl: "http://sync.demo.taler.net/";,
+    paymentProposalIds: [],
+    paymentStatus: {
+      type: ProviderPaymentType.TermsChanged,
       paidUntil: {
-        t_ms: 1656599921000
+        t_ms: 1656599921000,
       },
       newTerms: {
-        "annualFee": "EUR:10",
-        "storageLimitInMegabytes": 8,
-        "supportedProtocolVersion": "0.0"
+        annualFee: "EUR:10",
+        storageLimitInMegabytes: 8,
+        supportedProtocolVersion: "0.0",
       },
       oldTerms: {
-        "annualFee": "EUR:0.1",
-        "storageLimitInMegabytes": 16,
-        "supportedProtocolVersion": "0.0"
-      }
-    },
-    "terms": {
-      "annualFee": "EUR:0.1",
-      "storageLimitInMegabytes": 16,
-      "supportedProtocolVersion": "0.0"
-    }
-  }
+        annualFee: "EUR:0.1",
+        storageLimitInMegabytes: 16,
+        supportedProtocolVersion: "0.0",
+      },
+    },
+    terms: {
+      annualFee: "EUR:0.1",
+      storageLimitInMegabytes: 16,
+      supportedProtocolVersion: "0.0",
+    },
+  },
 });
-
diff --git 
a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx 
b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
index c45458eb..bd64b076 100644
--- a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
@@ -14,13 +14,23 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 
-
 import { i18n, Timestamp } from "@gnu-taler/taler-util";
-import { ProviderInfo, ProviderPaymentStatus, ProviderPaymentType } from 
"@gnu-taler/taler-wallet-core";
+import {
+  ProviderInfo,
+  ProviderPaymentStatus,
+  ProviderPaymentType,
+} from "@gnu-taler/taler-wallet-core";
 import { format, formatDuration, intervalToDuration } from "date-fns";
 import { Fragment, VNode, h } from "preact";
 import { ErrorMessage } from "../components/ErrorMessage";
-import { Button, ButtonDestructive, ButtonPrimary, PaymentStatus, WalletBox, 
SmallLightText } from "../components/styled";
+import {
+  Button,
+  ButtonDestructive,
+  ButtonPrimary,
+  PaymentStatus,
+  WalletBox,
+  SmallLightText,
+} from "../components/styled";
 import { useProviderStatus } from "../hooks/useProviderStatus";
 
 interface Props {
@@ -29,20 +39,29 @@ interface Props {
 }
 
 export function ProviderDetailPage({ pid, onBack }: Props): VNode {
-  const status = useProviderStatus(pid)
+  const status = useProviderStatus(pid);
   if (!status) {
-    return <div><i18n.Translate>Loading...</i18n.Translate></div>
+    return (
+      <div>
+        <i18n.Translate>Loading...</i18n.Translate>
+      </div>
+    );
   }
   if (!status.info) {
-    onBack()
-    return <div />
+    onBack();
+    return <div />;
   }
-  return <ProviderView info={status.info}
-    onSync={status.sync}
-    onDelete={() => status.remove().then(onBack)}
-    onBack={onBack}
-    onExtend={() => { null }}
-  />;
+  return (
+    <ProviderView
+      info={status.info}
+      onSync={status.sync}
+      onDelete={() => status.remove().then(onBack)}
+      onBack={onBack}
+      onExtend={() => {
+        null;
+      }}
+    />
+  );
 }
 
 export interface ViewProps {
@@ -53,124 +72,185 @@ export interface ViewProps {
   onExtend: () => void;
 }
 
-export function ProviderView({ info, onDelete, onSync, onBack, onExtend }: 
ViewProps): VNode {
-  const lb = info?.lastSuccessfulBackupTimestamp
-  const isPaid = info.paymentStatus.type === ProviderPaymentType.Paid || 
info.paymentStatus.type === ProviderPaymentType.TermsChanged
+export function ProviderView({
+  info,
+  onDelete,
+  onSync,
+  onBack,
+  onExtend,
+}: ViewProps): VNode {
+  const lb = info?.lastSuccessfulBackupTimestamp;
+  const isPaid =
+    info.paymentStatus.type === ProviderPaymentType.Paid ||
+    info.paymentStatus.type === ProviderPaymentType.TermsChanged;
   return (
     <WalletBox>
       <Error info={info} />
       <header>
-        <h3>{info.name} 
<SmallLightText>{info.syncProviderBaseUrl}</SmallLightText></h3>
-        <PaymentStatus color={isPaid ? 'rgb(28, 184, 65)' : 'rgb(202, 60, 
60)'}>{isPaid ? 'Paid' : 'Unpaid'}</PaymentStatus>
+        <h3>
+          {info.name}{" "}
+          <SmallLightText>{info.syncProviderBaseUrl}</SmallLightText>
+        </h3>
+        <PaymentStatus color={isPaid ? "rgb(28, 184, 65)" : "rgb(202, 60, 
60)"}>
+          {isPaid ? "Paid" : "Unpaid"}
+        </PaymentStatus>
       </header>
       <section>
-        <p><b>Last backup:</b> {lb == null || lb.t_ms == "never" ? "never" : 
format(lb.t_ms, 'dd MMM yyyy')} </p>
-        <ButtonPrimary onClick={onSync}><i18n.Translate>Back 
up</i18n.Translate></ButtonPrimary>
-        {info.terms && <Fragment>
-          <p><b>Provider fee:</b> {info.terms && info.terms.annualFee} per 
year</p>
-        </Fragment>
-        }
+        <p>
+          <b>Last backup:</b>{" "}
+          {lb == null || lb.t_ms == "never"
+            ? "never"
+            : format(lb.t_ms, "dd MMM yyyy")}{" "}
+        </p>
+        <ButtonPrimary onClick={onSync}>
+          <i18n.Translate>Back up</i18n.Translate>
+        </ButtonPrimary>
+        {info.terms && (
+          <Fragment>
+            <p>
+              <b>Provider fee:</b> {info.terms && info.terms.annualFee} per 
year
+            </p>
+          </Fragment>
+        )}
         <p>{descriptionByStatus(info.paymentStatus)}</p>
-        <ButtonPrimary disabled 
onClick={onExtend}><i18n.Translate>Extend</i18n.Translate></ButtonPrimary>
-
-        {info.paymentStatus.type === ProviderPaymentType.TermsChanged && <div>
-          <p><i18n.Translate>terms has changed, extending the service will 
imply accepting the new terms of service</i18n.Translate></p>
-          <table>
-            <thead>
-              <tr>
-                <td></td>
-                <td><i18n.Translate>old</i18n.Translate></td>
-                <td> -&gt;</td>
-                <td><i18n.Translate>new</i18n.Translate></td>
-              </tr>
-            </thead>
-            <tbody>
-
-              <tr>
-                <td><i18n.Translate>fee</i18n.Translate></td>
-                <td>{info.paymentStatus.oldTerms.annualFee}</td>
-                <td>-&gt;</td>
-                <td>{info.paymentStatus.newTerms.annualFee}</td>
-              </tr>
-              <tr>
-                <td><i18n.Translate>storage</i18n.Translate></td>
-                <td>{info.paymentStatus.oldTerms.storageLimitInMegabytes}</td>
-                <td>-&gt;</td>
-                <td>{info.paymentStatus.newTerms.storageLimitInMegabytes}</td>
-              </tr>
-            </tbody>
-          </table>
-        </div>}
+        <ButtonPrimary disabled onClick={onExtend}>
+          <i18n.Translate>Extend</i18n.Translate>
+        </ButtonPrimary>
 
+        {info.paymentStatus.type === ProviderPaymentType.TermsChanged && (
+          <div>
+            <p>
+              <i18n.Translate>
+                terms has changed, extending the service will imply accepting
+                the new terms of service
+              </i18n.Translate>
+            </p>
+            <table>
+              <thead>
+                <tr>
+                  <td></td>
+                  <td>
+                    <i18n.Translate>old</i18n.Translate>
+                  </td>
+                  <td> -&gt;</td>
+                  <td>
+                    <i18n.Translate>new</i18n.Translate>
+                  </td>
+                </tr>
+              </thead>
+              <tbody>
+                <tr>
+                  <td>
+                    <i18n.Translate>fee</i18n.Translate>
+                  </td>
+                  <td>{info.paymentStatus.oldTerms.annualFee}</td>
+                  <td>-&gt;</td>
+                  <td>{info.paymentStatus.newTerms.annualFee}</td>
+                </tr>
+                <tr>
+                  <td>
+                    <i18n.Translate>storage</i18n.Translate>
+                  </td>
+                  
<td>{info.paymentStatus.oldTerms.storageLimitInMegabytes}</td>
+                  <td>-&gt;</td>
+                  
<td>{info.paymentStatus.newTerms.storageLimitInMegabytes}</td>
+                </tr>
+              </tbody>
+            </table>
+          </div>
+        )}
       </section>
       <footer>
-        <Button onClick={onBack}><i18n.Translate> &lt; 
back</i18n.Translate></Button>
+        <Button onClick={onBack}>
+          <i18n.Translate> &lt; back</i18n.Translate>
+        </Button>
         <div>
-          <ButtonDestructive onClick={onDelete}><i18n.Translate>remove 
provider</i18n.Translate></ButtonDestructive>
+          <ButtonDestructive onClick={onDelete}>
+            <i18n.Translate>remove provider</i18n.Translate>
+          </ButtonDestructive>
         </div>
       </footer>
     </WalletBox>
-  )
+  );
 }
 
 function daysSince(d?: Timestamp) {
-  if (!d || d.t_ms === 'never') return 'never synced'
+  if (!d || d.t_ms === "never") return "never synced";
   const duration = intervalToDuration({
     start: d.t_ms,
     end: new Date(),
-  })
+  });
   const str = formatDuration(duration, {
-    delimiter: ', ',
+    delimiter: ", ",
     format: [
-      duration?.years ? i18n.str`years` : (
-        duration?.months ? i18n.str`months` : (
-          duration?.days ? i18n.str`days` : (
-            duration?.hours ? i18n.str`hours` : (
-              duration?.minutes ? i18n.str`minutes` : i18n.str`seconds`
-            )
-          )
-        )
-      )
-    ]
-  })
-  return `synced ${str} ago`
+      duration?.years
+        ? i18n.str`years`
+        : duration?.months
+        ? i18n.str`months`
+        : duration?.days
+        ? i18n.str`days`
+        : duration?.hours
+        ? i18n.str`hours`
+        : duration?.minutes
+        ? i18n.str`minutes`
+        : i18n.str`seconds`,
+    ],
+  });
+  return `synced ${str} ago`;
 }
 
 function Error({ info }: { info: ProviderInfo }) {
   if (info.lastError) {
-    return <ErrorMessage title={info.lastError.hint} />
+    return <ErrorMessage title={info.lastError.hint} />;
   }
   if (info.backupProblem) {
     switch (info.backupProblem.type) {
       case "backup-conflicting-device":
-        return <ErrorMessage title={<Fragment>
-          <i18n.Translate>There is conflict with another backup from 
<b>{info.backupProblem.otherDeviceId}</b></i18n.Translate>
-        </Fragment>} />
+        return (
+          <ErrorMessage
+            title={
+              <Fragment>
+                <i18n.Translate>
+                  There is conflict with another backup from{" "}
+                  <b>{info.backupProblem.otherDeviceId}</b>
+                </i18n.Translate>
+              </Fragment>
+            }
+          />
+        );
       case "backup-unreadable":
-        return <ErrorMessage title="Backup is not readable" />
+        return <ErrorMessage title="Backup is not readable" />;
       default:
-        return <ErrorMessage title={<Fragment>
-          <i18n.Translate>Unknown backup problem: 
{JSON.stringify(info.backupProblem)}</i18n.Translate>
-        </Fragment>} />
+        return (
+          <ErrorMessage
+            title={
+              <Fragment>
+                <i18n.Translate>
+                  Unknown backup problem: {JSON.stringify(info.backupProblem)}
+                </i18n.Translate>
+              </Fragment>
+            }
+          />
+        );
     }
   }
-  return null
+  return null;
 }
 
 function colorByStatus(status: ProviderPaymentType) {
   switch (status) {
     case ProviderPaymentType.InsufficientBalance:
-      return 'rgb(223, 117, 20)'
+      return "rgb(223, 117, 20)";
     case ProviderPaymentType.Unpaid:
-      return 'rgb(202, 60, 60)'
+      return "rgb(202, 60, 60)";
     case ProviderPaymentType.Paid:
-      return 'rgb(28, 184, 65)'
+      return "rgb(28, 184, 65)";
     case ProviderPaymentType.Pending:
-      return 'gray'
+      return "gray";
     case ProviderPaymentType.InsufficientBalance:
-      return 'rgb(202, 60, 60)'
+      return "rgb(202, 60, 60)";
     case ProviderPaymentType.TermsChanged:
-      return 'rgb(202, 60, 60)'
+      return "rgb(202, 60, 60)";
   }
 }
 
@@ -180,16 +260,19 @@ function descriptionByStatus(status: 
ProviderPaymentStatus) {
     // return i18n.str`not paid yet`
     case ProviderPaymentType.Paid:
     case ProviderPaymentType.TermsChanged:
-      if (status.paidUntil.t_ms === 'never') {
-        return i18n.str`service paid`
+      if (status.paidUntil.t_ms === "never") {
+        return i18n.str`service paid`;
       } else {
-        return <Fragment>
-          <b>Backup valid until:</b> {format(status.paidUntil.t_ms, 'dd MMM 
yyyy')}
-        </Fragment>
+        return (
+          <Fragment>
+            <b>Backup valid until:</b>{" "}
+            {format(status.paidUntil.t_ms, "dd MMM yyyy")}
+          </Fragment>
+        );
       }
     case ProviderPaymentType.Unpaid:
     case ProviderPaymentType.InsufficientBalance:
     case ProviderPaymentType.Pending:
-      return ''
+      return "";
   }
 }
diff --git 
a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.stories.tsx
index ca524f4e..c552b19b 100644
--- a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.stories.tsx
@@ -15,26 +15,23 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample } from '../test-utils';
-import { ReserveCreated as TestedComponent } from './ReserveCreated';
+import { createExample } from "../test-utils";
+import { ReserveCreated as TestedComponent } from "./ReserveCreated";
 
 export default {
-  title: 'wallet/manual withdraw/reserve created',
+  title: "wallet/manual withdraw/reserve created",
   component: TestedComponent,
-  argTypes: {
-  }
+  argTypes: {},
 };
 
-
 export const InitialState = createExample(TestedComponent, {
-  reservePub: 'ASLKDJQWLKEJASLKDJSADLKASJDLKSADJ',
+  reservePub: "ASLKDJQWLKEJASLKDJSADLKASJDLKSADJ",
   paytos: [
-    
'payto://x-taler-bank/bank.taler:5882/exchangeminator?amount=COL%3A1&message=Taler+Withdrawal+A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG',
-    
'payto://x-taler-bank/international-bank.com/myaccount?amount=COL%3A1&message=Taler+Withdrawal+TYQTE7VA4M9GZQ4TR06YBNGA05AJGMFNSK4Q62NXR2FKNDB1J4EX',
-  ]
+    
"payto://x-taler-bank/bank.taler:5882/exchangeminator?amount=COL%3A1&message=Taler+Withdrawal+A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG",
+    
"payto://x-taler-bank/international-bank.com/myaccount?amount=COL%3A1&message=Taler+Withdrawal+TYQTE7VA4M9GZQ4TR06YBNGA05AJGMFNSK4Q62NXR2FKNDB1J4EX",
+  ],
 });
-
diff --git a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx 
b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx
index e01336e0..9008e975 100644
--- a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx
@@ -1,8 +1,7 @@
-import { Fragment, VNode } from "preact";
+import { h, Fragment, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { QR } from "../components/QR";
 import { ButtonBox, FontIcon, WalletBox } from "../components/styled";
-
 export interface Props {
   reservePub: string;
   paytos: string[];
@@ -10,30 +9,57 @@ export interface Props {
 }
 
 export function ReserveCreated({ reservePub, paytos, onBack }: Props): VNode {
-  const [opened, setOpened] = useState(-1)
+  const [opened, setOpened] = useState(-1);
   return (
     <WalletBox>
       <section>
         <h2>Reserve created!</h2>
-        <p>Now you need to send money to the exchange to one of the following 
accounts</p>
-        <p>To complete the setup of the reserve, you must now initiate a wire 
transfer using the given wire transfer subject and crediting the specified 
amount to the indicated account of the exchange.</p>
+        <p>
+          Now you need to send money to the exchange to one of the following
+          accounts
+        </p>
+        <p>
+          To complete the setup of the reserve, you must now initiate a wire
+          transfer using the given wire transfer subject and crediting the
+          specified amount to the indicated account of the exchange.
+        </p>
       </section>
       <section>
         <ul>
           {paytos.map((href, idx) => {
-            const url = new URL(href)
-            return <li key={idx}><p>
-              <a href="" onClick={(e) => { setOpened(o => o === idx ? -1 : 
idx); e.preventDefault() }}>{url.pathname}</a>
-              {opened === idx && <Fragment>
-                <p>If your system supports RFC 8905, you can do this by 
opening <a href={href}>this URI</a> or scan the QR with your wallet</p>
-                <QR text={href} />
-              </Fragment>}
-            </p></li>
+            const url = new URL(href);
+            return (
+              <li key={idx}>
+                <p>
+                  <a
+                    href=""
+                    onClick={(e) => {
+                      setOpened((o) => (o === idx ? -1 : idx));
+                      e.preventDefault();
+                    }}
+                  >
+                    {url.pathname}
+                  </a>
+                  {opened === idx && (
+                    <Fragment>
+                      <p>
+                        If your system supports RFC 8905, you can do this by
+                        opening <a href={href}>this URI</a> or scan the QR with
+                        your wallet
+                      </p>
+                      <QR text={href} />
+                    </Fragment>
+                  )}
+                </p>
+              </li>
+            );
           })}
         </ul>
       </section>
       <footer>
-        <ButtonBox onClick={onBack}><FontIcon>&#x2190;</FontIcon></ButtonBox>
+        <ButtonBox onClick={onBack}>
+          <FontIcon>&#x2190;</FontIcon>
+        </ButtonBox>
         <div />
       </footer>
     </WalletBox>
diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx
index a04a0b4f..6cc1368d 100644
--- a/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx
@@ -15,39 +15,41 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
-import { createExample } from '../test-utils';
-import { SettingsView as TestedComponent } from './Settings';
+import { createExample } from "../test-utils";
+import { SettingsView as TestedComponent } from "./Settings";
 
 export default {
-  title: 'wallet/settings',
+  title: "wallet/settings",
   component: TestedComponent,
   argTypes: {
     setDeviceName: () => Promise.resolve(),
-  }
+  },
 };
 
 export const AllOff = createExample(TestedComponent, {
-  deviceName: 'this-is-the-device-name',
+  deviceName: "this-is-the-device-name",
   setDeviceName: () => Promise.resolve(),
 });
 
 export const OneChecked = createExample(TestedComponent, {
-  deviceName: 'this-is-the-device-name',
+  deviceName: "this-is-the-device-name",
   permissionsEnabled: true,
   setDeviceName: () => Promise.resolve(),
 });
 
 export const WithOneExchange = createExample(TestedComponent, {
-  deviceName: 'this-is-the-device-name',
+  deviceName: "this-is-the-device-name",
   permissionsEnabled: true,
   setDeviceName: () => Promise.resolve(),
-  knownExchanges: [{
-    currency: 'USD',
-    exchangeBaseUrl: 'http://exchange.taler',
-    paytoUris: ['payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator']
-  }]
+  knownExchanges: [
+    {
+      currency: "USD",
+      exchangeBaseUrl: "http://exchange.taler";,
+      paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"],
+    },
+  ],
 });
diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx 
b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
index 8d18586b..8d8f3cdb 100644
--- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
@@ -14,7 +14,6 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 
-
 import { ExchangeListItem, i18n } from "@gnu-taler/taler-util";
 import { VNode, h, Fragment } from "preact";
 import { Checkbox } from "../components/Checkbox";
@@ -30,18 +29,28 @@ import * as wxApi from "../wxApi";
 
 export function SettingsPage(): VNode {
   const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
-  const { devMode, toggleDevMode } = useDevContext()
-  const { name, update } = useBackupDeviceName()
-  const [lang, changeLang] = useLang()
+  const { devMode, toggleDevMode } = useDevContext();
+  const { name, update } = useBackupDeviceName();
+  const [lang, changeLang] = useLang();
   const exchangesHook = useAsyncAsHook(() => wxApi.listExchanges());
 
-  return <SettingsView
-    lang={lang} changeLang={changeLang}
-    knownExchanges={!exchangesHook || exchangesHook.hasError ? [] : 
exchangesHook.response.exchanges}
-    deviceName={name} setDeviceName={update}
-    permissionsEnabled={permissionsEnabled} 
togglePermissions={togglePermissions}
-    developerMode={devMode} toggleDeveloperMode={toggleDevMode}
-  />;
+  return (
+    <SettingsView
+      lang={lang}
+      changeLang={changeLang}
+      knownExchanges={
+        !exchangesHook || exchangesHook.hasError
+          ? []
+          : exchangesHook.response.exchanges
+      }
+      deviceName={name}
+      setDeviceName={update}
+      permissionsEnabled={permissionsEnabled}
+      togglePermissions={togglePermissions}
+      developerMode={devMode}
+      toggleDeveloperMode={toggleDevMode}
+    />
+  );
 }
 
 export interface ViewProps {
@@ -56,52 +65,72 @@ export interface ViewProps {
   knownExchanges: Array<ExchangeListItem>;
 }
 
-import { strings as messages } from '../i18n/strings'
+import { strings as messages } from "../i18n/strings";
 
 type LangsNames = {
-  [P in keyof typeof messages]: string
-}
+  [P in keyof typeof messages]: string;
+};
 
 const names: LangsNames = {
-  es: 'Español [es]',
-  en: 'English [en]',
-  fr: 'Français [fr]',
-  de: 'Deutsch [de]',
-  sv: 'Svenska [sv]',
-  it: 'Italiano [it]',
-}
+  es: "Español [es]",
+  en: "English [en]",
+  fr: "Français [fr]",
+  de: "Deutsch [de]",
+  sv: "Svenska [sv]",
+  it: "Italiano [it]",
+};
 
-
-export function SettingsView({ knownExchanges, lang, changeLang, deviceName, 
setDeviceName, permissionsEnabled, togglePermissions, developerMode, 
toggleDeveloperMode }: ViewProps): VNode {
+export function SettingsView({
+  knownExchanges,
+  lang,
+  changeLang,
+  deviceName,
+  setDeviceName,
+  permissionsEnabled,
+  togglePermissions,
+  developerMode,
+  toggleDeveloperMode,
+}: ViewProps): VNode {
   return (
     <WalletBox>
       <section>
-
-        <h2><i18n.Translate>Known exchanges</i18n.Translate></h2>
-        {!knownExchanges || !knownExchanges.length ? <div>
-          No exchange yet!
-        </div> :
+        <h2>
+          <i18n.Translate>Known exchanges</i18n.Translate>
+        </h2>
+        {!knownExchanges || !knownExchanges.length ? (
+          <div>No exchange yet!</div>
+        ) : (
           <table>
-            {knownExchanges.map(e => <tr>
-              <td>{e.currency}</td>
-              <td><a href={e.exchangeBaseUrl}>{e.exchangeBaseUrl}</a></td>
-            </tr>)}
+            {knownExchanges.map((e) => (
+              <tr>
+                <td>{e.currency}</td>
+                <td>
+                  <a href={e.exchangeBaseUrl}>{e.exchangeBaseUrl}</a>
+                </td>
+              </tr>
+            ))}
           </table>
-        }
-        
-        <h2><i18n.Translate>Permissions</i18n.Translate></h2>
-        <Checkbox label="Automatically open wallet based on page content"
+        )}
+
+        <h2>
+          <i18n.Translate>Permissions</i18n.Translate>
+        </h2>
+        <Checkbox
+          label="Automatically open wallet based on page content"
           name="perm"
           description="(Enabling this option below will make using the wallet 
faster, but requires more permissions from your browser.)"
-          enabled={permissionsEnabled} onToggle={togglePermissions}
+          enabled={permissionsEnabled}
+          onToggle={togglePermissions}
         />
         <h2>Config</h2>
-        <Checkbox label="Developer mode"
+        <Checkbox
+          label="Developer mode"
           name="devMode"
           description="(More options and information useful for debugging)"
-          enabled={developerMode} onToggle={toggleDeveloperMode}
+          enabled={developerMode}
+          onToggle={toggleDeveloperMode}
         />
       </section>
     </WalletBox>
-  )
+  );
 }
diff --git 
a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
index 535509ce..c9a3f47c 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
@@ -15,110 +15,116 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
 import {
   PaymentStatus,
-  TransactionCommon, TransactionDeposit, TransactionPayment,
-  TransactionRefresh, TransactionRefund, TransactionTip, TransactionType,
+  TransactionCommon,
+  TransactionDeposit,
+  TransactionPayment,
+  TransactionRefresh,
+  TransactionRefund,
+  TransactionTip,
+  TransactionType,
   TransactionWithdrawal,
-  WithdrawalType
-} from '@gnu-taler/taler-util';
-import { createExample } from '../test-utils';
-import { TransactionView as TestedComponent } from './Transaction';
+  WithdrawalType,
+} from "@gnu-taler/taler-util";
+import { createExample } from "../test-utils";
+import { TransactionView as TestedComponent } from "./Transaction";
 
 export default {
-  title: 'wallet/history/details',
+  title: "wallet/history/details",
   component: TestedComponent,
   argTypes: {
-    onRetry: { action: 'onRetry' },
-    onDelete: { action: 'onDelete' },
-    onBack: { action: 'onBack' },
-  }
+    onRetry: { action: "onRetry" },
+    onDelete: { action: "onDelete" },
+    onBack: { action: "onBack" },
+  },
 };
 
 const commonTransaction = {
-  amountRaw: 'KUDOS:11',
-  amountEffective: 'KUDOS:9.2',
+  amountRaw: "KUDOS:11",
+  amountEffective: "KUDOS:9.2",
   pending: false,
   timestamp: {
-    t_ms: new Date().getTime()
+    t_ms: new Date().getTime(),
   },
-  transactionId: '12',
-} as TransactionCommon
+  transactionId: "12",
+} as TransactionCommon;
 
 const exampleData = {
   withdraw: {
     ...commonTransaction,
     type: TransactionType.Withdrawal,
-    exchangeBaseUrl: 'http://exchange.taler',
+    exchangeBaseUrl: "http://exchange.taler";,
     withdrawalDetails: {
       confirmed: false,
-      exchangePaytoUris: ['payto://x-taler-bank/bank/account'],
+      exchangePaytoUris: ["payto://x-taler-bank/bank/account"],
       type: WithdrawalType.ManualTransfer,
-    }
+    },
   } as TransactionWithdrawal,
   payment: {
     ...commonTransaction,
-    amountEffective: 'KUDOS:11',
+    amountEffective: "KUDOS:11",
     type: TransactionType.Payment,
     info: {
-      contractTermsHash: 'ASDZXCASD',
+      contractTermsHash: "ASDZXCASD",
       merchant: {
-        name: 'the merchant',
+        name: "the merchant",
       },
-      orderId: '2021.167-03NPY6MCYMVGT',
+      orderId: "2021.167-03NPY6MCYMVGT",
       products: [],
       summary: "Essay: Why the Devil's Advocate Doesn't Help Reach the Truth",
-      fulfillmentMessage: '',
+      fulfillmentMessage: "",
     },
-    proposalId: '1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0',
+    proposalId: "1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
     status: PaymentStatus.Accepted,
   } as TransactionPayment,
   deposit: {
     ...commonTransaction,
     type: TransactionType.Deposit,
-    depositGroupId: '#groupId',
-    targetPaytoUri: 'payto://x-taler-bank/bank/account',
+    depositGroupId: "#groupId",
+    targetPaytoUri: "payto://x-taler-bank/bank/account",
   } as TransactionDeposit,
   refresh: {
     ...commonTransaction,
     type: TransactionType.Refresh,
-    exchangeBaseUrl: 'http://exchange.taler',
+    exchangeBaseUrl: "http://exchange.taler";,
   } as TransactionRefresh,
   tip: {
     ...commonTransaction,
     type: TransactionType.Tip,
-    merchantBaseUrl: 'http://merchant.taler',
+    merchantBaseUrl: "http://merchant.taler";,
   } as TransactionTip,
   refund: {
     ...commonTransaction,
     type: TransactionType.Refund,
-    refundedTransactionId: 
'payment:1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0',
+    refundedTransactionId:
+      "payment:1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
     info: {
-      contractTermsHash: 'ASDZXCASD',
+      contractTermsHash: "ASDZXCASD",
       merchant: {
-        name: 'the merchant',
+        name: "the merchant",
       },
-      orderId: '2021.167-03NPY6MCYMVGT',
+      orderId: "2021.167-03NPY6MCYMVGT",
       products: [],
-      summary: 'the summary',
-      fulfillmentMessage: '',
+      summary: "the summary",
+      fulfillmentMessage: "",
     },
   } as TransactionRefund,
-}
+};
 
 const transactionError = {
   code: 2000,
   details: "details",
   hint: "this is a hint for the error",
-  message: 'message'
-}
+  message: "message",
+};
 
 export const Withdraw = createExample(TestedComponent, {
-  transaction: exampleData.withdraw
+  transaction: exampleData.withdraw,
 });
 
 export const WithdrawError = createExample(TestedComponent, {
@@ -132,24 +138,22 @@ export const WithdrawPending = 
createExample(TestedComponent, {
   transaction: { ...exampleData.withdraw, pending: true },
 });
 
-
 export const Payment = createExample(TestedComponent, {
-  transaction: exampleData.payment
+  transaction: exampleData.payment,
 });
 
 export const PaymentError = createExample(TestedComponent, {
   transaction: {
     ...exampleData.payment,
-    error: transactionError
+    error: transactionError,
   },
 });
 
 export const PaymentWithoutFee = createExample(TestedComponent, {
   transaction: {
     ...exampleData.payment,
-    amountRaw: 'KUDOS:11',
-
-  }
+    amountRaw: "KUDOS:11",
+  },
 });
 
 export const PaymentPending = createExample(TestedComponent, {
@@ -161,27 +165,33 @@ export const PaymentWithProducts = 
createExample(TestedComponent, {
     ...exampleData.payment,
     info: {
       ...exampleData.payment.info,
-      summary: 'this order has 5 products',
-      products: [{
-        description: 't-shirt',
-        unit: 'shirts',
-        quantity: 1,
-      }, {
-        description: 't-shirt',
-        unit: 'shirts',
-        quantity: 1,
-      }, {
-        description: 'e-book',
-      }, {
-        description: 'beer',
-        unit: 'pint',
-        quantity: 15,
-      }, {
-        description: 'beer',
-        unit: 'pint',
-        quantity: 15,
-      }]
-    }
+      summary: "this order has 5 products",
+      products: [
+        {
+          description: "t-shirt",
+          unit: "shirts",
+          quantity: 1,
+        },
+        {
+          description: "t-shirt",
+          unit: "shirts",
+          quantity: 1,
+        },
+        {
+          description: "e-book",
+        },
+        {
+          description: "beer",
+          unit: "pint",
+          quantity: 15,
+        },
+        {
+          description: "beer",
+          unit: "pint",
+          quantity: 15,
+        },
+      ],
+    },
   } as TransactionPayment,
 });
 
@@ -190,75 +200,79 @@ export const PaymentWithLongSummary = 
createExample(TestedComponent, {
     ...exampleData.payment,
     info: {
       ...exampleData.payment.info,
-      summary: 'this is a very long summary that will occupy severals lines, 
this is a very long summary that will occupy severals lines, this is a very 
long summary that will occupy severals lines, this is a very long summary that 
will occupy severals lines, ',
-      products: [{
-        description: 'an xl sized t-shirt with some drawings on it, color 
pink',
-        unit: 'shirts',
-        quantity: 1,
-      }, {
-        description: 'beer',
-        unit: 'pint',
-        quantity: 15,
-      }]
-    }
+      summary:
+        "this is a very long summary that will occupy severals lines, this is 
a very long summary that will occupy severals lines, this is a very long 
summary that will occupy severals lines, this is a very long summary that will 
occupy severals lines, ",
+      products: [
+        {
+          description:
+            "an xl sized t-shirt with some drawings on it, color pink",
+          unit: "shirts",
+          quantity: 1,
+        },
+        {
+          description: "beer",
+          unit: "pint",
+          quantity: 15,
+        },
+      ],
+    },
   } as TransactionPayment,
 });
 
-
 export const Deposit = createExample(TestedComponent, {
-  transaction: exampleData.deposit
+  transaction: exampleData.deposit,
 });
 
 export const DepositError = createExample(TestedComponent, {
   transaction: {
     ...exampleData.deposit,
-    error: transactionError
+    error: transactionError,
   },
 });
 
 export const DepositPending = createExample(TestedComponent, {
-  transaction: { ...exampleData.deposit, pending: true }
+  transaction: { ...exampleData.deposit, pending: true },
 });
 
 export const Refresh = createExample(TestedComponent, {
-  transaction: exampleData.refresh
+  transaction: exampleData.refresh,
 });
 
 export const RefreshError = createExample(TestedComponent, {
   transaction: {
     ...exampleData.refresh,
-    error: transactionError
+    error: transactionError,
   },
 });
 
 export const Tip = createExample(TestedComponent, {
-  transaction: exampleData.tip
+  transaction: exampleData.tip,
 });
 
 export const TipError = createExample(TestedComponent, {
   transaction: {
     ...exampleData.tip,
-    error: transactionError
+    error: transactionError,
   },
 });
 
 export const TipPending = createExample(TestedComponent, {
-  transaction: { ...exampleData.tip, pending: true }
+  transaction: { ...exampleData.tip, pending: true },
 });
 
 export const Refund = createExample(TestedComponent, {
-  transaction: exampleData.refund
+  transaction: exampleData.refund,
 });
 
 export const RefundError = createExample(TestedComponent, {
   transaction: {
     ...exampleData.refund,
-    error: transactionError
+    error: transactionError,
   },
 });
 
 export const RefundPending = createExample(TestedComponent, {
-  transaction: { ...exampleData.refund, pending: true }
+  transaction: { ...exampleData.refund, pending: true },
 });
 
 export const RefundWithProducts = createExample(TestedComponent, {
@@ -266,11 +280,14 @@ export const RefundWithProducts = 
createExample(TestedComponent, {
     ...exampleData.refund,
     info: {
       ...exampleData.refund.info,
-      products: [{
-        description: 't-shirt',
-      }, {
-        description: 'beer',
-      }]
-    }
+      products: [
+        {
+          description: "t-shirt",
+        },
+        {
+          description: "beer",
+        },
+      ],
+    },
   } as TransactionRefund,
 });
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx 
b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
index cf41efb5..7de6982e 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
@@ -14,27 +14,43 @@
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { AmountLike, Amounts, i18n, Transaction, TransactionType } from 
"@gnu-taler/taler-util";
+import {
+  AmountLike,
+  Amounts,
+  i18n,
+  Transaction,
+  TransactionType,
+} from "@gnu-taler/taler-util";
 import { format } from "date-fns";
-import { JSX, VNode } from "preact";
-import { route } from 'preact-router';
+import { JSX, VNode, h } from "preact";
+import { route } from "preact-router";
 import { useEffect, useState } from "preact/hooks";
 import emptyImg from "../../static/img/empty.png";
 import { ErrorMessage } from "../components/ErrorMessage";
 import { Part } from "../components/Part";
-import { ButtonBox, ButtonBoxDestructive, ButtonPrimary, FontIcon, 
ListOfProducts, RowBorderGray, SmallLightText, WalletBox, WarningBox } from 
"../components/styled";
+import {
+  ButtonBox,
+  ButtonBoxDestructive,
+  ButtonPrimary,
+  FontIcon,
+  ListOfProducts,
+  RowBorderGray,
+  SmallLightText,
+  WalletBox,
+  WarningBox,
+} from "../components/styled";
 import { Pages } from "../NavigationBar";
 import * as wxApi from "../wxApi";
 
-export function TransactionPage({ tid }: { tid: string; }): JSX.Element {
-  const [transaction, setTransaction] = useState<
-    Transaction | undefined
-  >(undefined);
+export function TransactionPage({ tid }: { tid: string }): JSX.Element {
+  const [transaction, setTransaction] = useState<Transaction | undefined>(
+    undefined,
+  );
 
   useEffect(() => {
     const fetchData = async (): Promise<void> => {
       const res = await wxApi.getTransactions();
-      const ts = res.transactions.filter(t => t.transactionId === tid);
+      const ts = res.transactions.filter((t) => t.transactionId === tid);
       if (ts.length === 1) {
         setTransaction(ts[0]);
       } else {
@@ -45,13 +61,22 @@ export function TransactionPage({ tid }: { tid: string; }): 
JSX.Element {
   }, [tid]);
 
   if (!transaction) {
-    return <div><i18n.Translate>Loading ...</i18n.Translate></div>;
+    return (
+      <div>
+        <i18n.Translate>Loading ...</i18n.Translate>
+      </div>
+    );
   }
-  return <TransactionView
-    transaction={transaction}
-    onDelete={() => wxApi.deleteTransaction(tid).then(_ => history.go(-1))}
-    onRetry={() => wxApi.retryTransaction(tid).then(_ => history.go(-1))}
-    onBack={() => { route(Pages.history) }} />;
+  return (
+    <TransactionView
+      transaction={transaction}
+      onDelete={() => wxApi.deleteTransaction(tid).then((_) => history.go(-1))}
+      onRetry={() => wxApi.retryTransaction(tid).then((_) => history.go(-1))}
+      onBack={() => {
+        route(Pages.history);
+      }}
+    />
+  );
 }
 
 export interface WalletTransactionProps {
@@ -61,173 +86,310 @@ export interface WalletTransactionProps {
   onBack: () => void;
 }
 
-export function TransactionView({ transaction, onDelete, onRetry, onBack }: 
WalletTransactionProps) {
-
+export function TransactionView({
+  transaction,
+  onDelete,
+  onRetry,
+  onBack,
+}: WalletTransactionProps) {
   function TransactionTemplate({ children }: { children: VNode[] }) {
-    return <WalletBox>
-      <section style={{ padding: 8, textAlign: 'center'}}>
-        <ErrorMessage title={transaction?.error?.hint} />
-        {transaction.pending && <WarningBox>This transaction is not 
completed</WarningBox>}
-      </section>
-      <section>
-        <div style={{ textAlign: 'center' }}>
-          {children}
-        </div>
-      </section>
-      <footer>
-        <ButtonBox onClick={onBack}><i18n.Translate> 
<FontIcon>&#x2190;</FontIcon> </i18n.Translate></ButtonBox>
-        <div>
-          {transaction?.error ? <ButtonPrimary 
onClick={onRetry}><i18n.Translate>retry</i18n.Translate></ButtonPrimary> : null}
-          <ButtonBoxDestructive 
onClick={onDelete}><i18n.Translate>&#x1F5D1;</i18n.Translate></ButtonBoxDestructive>
-        </div>
-      </footer>
-    </WalletBox>
+    return (
+      <WalletBox>
+        <section style={{ padding: 8, textAlign: "center" }}>
+          <ErrorMessage title={transaction?.error?.hint} />
+          {transaction.pending && (
+            <WarningBox>This transaction is not completed</WarningBox>
+          )}
+        </section>
+        <section>
+          <div style={{ textAlign: "center" }}>{children}</div>
+        </section>
+        <footer>
+          <ButtonBox onClick={onBack}>
+            <i18n.Translate>
+              {" "}
+              <FontIcon>&#x2190;</FontIcon>{" "}
+            </i18n.Translate>
+          </ButtonBox>
+          <div>
+            {transaction?.error ? (
+              <ButtonPrimary onClick={onRetry}>
+                <i18n.Translate>retry</i18n.Translate>
+              </ButtonPrimary>
+            ) : null}
+            <ButtonBoxDestructive onClick={onDelete}>
+              <i18n.Translate>&#x1F5D1;</i18n.Translate>
+            </ButtonBoxDestructive>
+          </div>
+        </footer>
+      </WalletBox>
+    );
   }
 
   function amountToString(text: AmountLike) {
-    const aj = Amounts.jsonifyAmount(text)
-    const amount = Amounts.stringifyValue(aj)
-    return `${amount} ${aj.currency}`
+    const aj = Amounts.jsonifyAmount(text);
+    const amount = Amounts.stringifyValue(aj);
+    return `${amount} ${aj.currency}`;
   }
 
-
   if (transaction.type === TransactionType.Withdrawal) {
     const fee = Amounts.sub(
       Amounts.parseOrThrow(transaction.amountRaw),
       Amounts.parseOrThrow(transaction.amountEffective),
-    ).amount
-    return <TransactionTemplate>
-      <h2>Withdrawal</h2>
-      <div>{transaction.timestamp.t_ms === 'never' ? 'never' : 
format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')}</div>
-      <br />
-      <Part title="Total withdrawn" 
text={amountToString(transaction.amountEffective)} kind='positive' />
-      <Part title="Chosen amount" text={amountToString(transaction.amountRaw)} 
kind='neutral' />
-      <Part title="Exchange fee" text={amountToString(fee)} kind='negative' />
-      <Part title="Exchange" text={new 
URL(transaction.exchangeBaseUrl).hostname} kind='neutral' />
-    </TransactionTemplate>
+    ).amount;
+    return (
+      <TransactionTemplate>
+        <h2>Withdrawal</h2>
+        <div>
+          {transaction.timestamp.t_ms === "never"
+            ? "never"
+            : format(transaction.timestamp.t_ms, "dd MMMM yyyy, HH:mm")}
+        </div>
+        <br />
+        <Part
+          title="Total withdrawn"
+          text={amountToString(transaction.amountEffective)}
+          kind="positive"
+        />
+        <Part
+          title="Chosen amount"
+          text={amountToString(transaction.amountRaw)}
+          kind="neutral"
+        />
+        <Part title="Exchange fee" text={amountToString(fee)} kind="negative" 
/>
+        <Part
+          title="Exchange"
+          text={new URL(transaction.exchangeBaseUrl).hostname}
+          kind="neutral"
+        />
+      </TransactionTemplate>
+    );
   }
 
-  const showLargePic = () => {
-
-  }
+  const showLargePic = () => {};
 
   if (transaction.type === TransactionType.Payment) {
     const fee = Amounts.sub(
       Amounts.parseOrThrow(transaction.amountEffective),
       Amounts.parseOrThrow(transaction.amountRaw),
-    ).amount
-
-    return <TransactionTemplate>
-      <h2>Payment </h2>
-      <div>{transaction.timestamp.t_ms === 'never' ? 'never' : 
format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')}</div>
-      <br />
-      <Part big title="Total paid" 
text={amountToString(transaction.amountEffective)} kind='negative' />
-      <Part big title="Purchase amount" 
text={amountToString(transaction.amountRaw)} kind='neutral' />
-      <Part big title="Fee" text={amountToString(fee)} kind='negative' />
-      <Part title="Merchant" text={transaction.info.merchant.name} 
kind='neutral' />
-      <Part title="Purchase" text={transaction.info.summary} kind='neutral' />
-      <Part title="Receipt" text={`#${transaction.info.orderId}`} 
kind='neutral' />
+    ).amount;
 
-      <div>
-        {transaction.info.products && transaction.info.products.length > 0 &&
-          <ListOfProducts>
-            {transaction.info.products.map((p, k) => <RowBorderGray key={k}>
-              <a href="#" onClick={showLargePic}>
-                <img src={p.image ? p.image : emptyImg} />
-              </a>
-              <div>
-                {p.quantity && p.quantity > 0 && <SmallLightText>x 
{p.quantity} {p.unit}</SmallLightText>}
-                <div>{p.description}</div>
-              </div>
-            </RowBorderGray>)}
-          </ListOfProducts>
-        }
-      </div>
-    </TransactionTemplate>
+    return (
+      <TransactionTemplate>
+        <h2>Payment </h2>
+        <div>
+          {transaction.timestamp.t_ms === "never"
+            ? "never"
+            : format(transaction.timestamp.t_ms, "dd MMMM yyyy, HH:mm")}
+        </div>
+        <br />
+        <Part
+          big
+          title="Total paid"
+          text={amountToString(transaction.amountEffective)}
+          kind="negative"
+        />
+        <Part
+          big
+          title="Purchase amount"
+          text={amountToString(transaction.amountRaw)}
+          kind="neutral"
+        />
+        <Part big title="Fee" text={amountToString(fee)} kind="negative" />
+        <Part
+          title="Merchant"
+          text={transaction.info.merchant.name}
+          kind="neutral"
+        />
+        <Part title="Purchase" text={transaction.info.summary} kind="neutral" 
/>
+        <Part
+          title="Receipt"
+          text={`#${transaction.info.orderId}`}
+          kind="neutral"
+        />
+
+        <div>
+          {transaction.info.products && transaction.info.products.length > 0 
&& (
+            <ListOfProducts>
+              {transaction.info.products.map((p, k) => (
+                <RowBorderGray key={k}>
+                  <a href="#" onClick={showLargePic}>
+                    <img src={p.image ? p.image : emptyImg} />
+                  </a>
+                  <div>
+                    {p.quantity && p.quantity > 0 && (
+                      <SmallLightText>
+                        x {p.quantity} {p.unit}
+                      </SmallLightText>
+                    )}
+                    <div>{p.description}</div>
+                  </div>
+                </RowBorderGray>
+              ))}
+            </ListOfProducts>
+          )}
+        </div>
+      </TransactionTemplate>
+    );
   }
 
   if (transaction.type === TransactionType.Deposit) {
     const fee = Amounts.sub(
       Amounts.parseOrThrow(transaction.amountRaw),
       Amounts.parseOrThrow(transaction.amountEffective),
-    ).amount
-    return <TransactionTemplate>
-      <h2>Deposit </h2>
-      <div>{transaction.timestamp.t_ms === 'never' ? 'never' : 
format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')}</div>
-      <br />
-      <Part big title="Total deposit" 
text={amountToString(transaction.amountEffective)} kind='negative' />
-      <Part big title="Purchase amount" 
text={amountToString(transaction.amountRaw)} kind='neutral' />
-      <Part big title="Fee" text={amountToString(fee)} kind='negative' />
-    </TransactionTemplate>
+    ).amount;
+    return (
+      <TransactionTemplate>
+        <h2>Deposit </h2>
+        <div>
+          {transaction.timestamp.t_ms === "never"
+            ? "never"
+            : format(transaction.timestamp.t_ms, "dd MMMM yyyy, HH:mm")}
+        </div>
+        <br />
+        <Part
+          big
+          title="Total deposit"
+          text={amountToString(transaction.amountEffective)}
+          kind="negative"
+        />
+        <Part
+          big
+          title="Purchase amount"
+          text={amountToString(transaction.amountRaw)}
+          kind="neutral"
+        />
+        <Part big title="Fee" text={amountToString(fee)} kind="negative" />
+      </TransactionTemplate>
+    );
   }
 
   if (transaction.type === TransactionType.Refresh) {
     const fee = Amounts.sub(
       Amounts.parseOrThrow(transaction.amountRaw),
       Amounts.parseOrThrow(transaction.amountEffective),
-    ).amount
-    return <TransactionTemplate>
-      <h2>Refresh</h2>
-      <div>{transaction.timestamp.t_ms === 'never' ? 'never' : 
format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')}</div>
-      <br />
-      <Part big title="Total refresh" 
text={amountToString(transaction.amountEffective)} kind='negative' />
-      <Part big title="Refresh amount" 
text={amountToString(transaction.amountRaw)} kind='neutral' />
-      <Part big title="Fee" text={amountToString(fee)} kind='negative' />
-    </TransactionTemplate>
+    ).amount;
+    return (
+      <TransactionTemplate>
+        <h2>Refresh</h2>
+        <div>
+          {transaction.timestamp.t_ms === "never"
+            ? "never"
+            : format(transaction.timestamp.t_ms, "dd MMMM yyyy, HH:mm")}
+        </div>
+        <br />
+        <Part
+          big
+          title="Total refresh"
+          text={amountToString(transaction.amountEffective)}
+          kind="negative"
+        />
+        <Part
+          big
+          title="Refresh amount"
+          text={amountToString(transaction.amountRaw)}
+          kind="neutral"
+        />
+        <Part big title="Fee" text={amountToString(fee)} kind="negative" />
+      </TransactionTemplate>
+    );
   }
 
   if (transaction.type === TransactionType.Tip) {
     const fee = Amounts.sub(
       Amounts.parseOrThrow(transaction.amountRaw),
       Amounts.parseOrThrow(transaction.amountEffective),
-    ).amount
-    return <TransactionTemplate>
-      <h2>Tip</h2>
-      <div>{transaction.timestamp.t_ms === 'never' ? 'never' : 
format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')}</div>
-      <br />
-      <Part big title="Total tip" 
text={amountToString(transaction.amountEffective)} kind='positive' />
-      <Part big title="Received amount" 
text={amountToString(transaction.amountRaw)} kind='neutral' />
-      <Part big title="Fee" text={amountToString(fee)} kind='negative' />
-    </TransactionTemplate>
+    ).amount;
+    return (
+      <TransactionTemplate>
+        <h2>Tip</h2>
+        <div>
+          {transaction.timestamp.t_ms === "never"
+            ? "never"
+            : format(transaction.timestamp.t_ms, "dd MMMM yyyy, HH:mm")}
+        </div>
+        <br />
+        <Part
+          big
+          title="Total tip"
+          text={amountToString(transaction.amountEffective)}
+          kind="positive"
+        />
+        <Part
+          big
+          title="Received amount"
+          text={amountToString(transaction.amountRaw)}
+          kind="neutral"
+        />
+        <Part big title="Fee" text={amountToString(fee)} kind="negative" />
+      </TransactionTemplate>
+    );
   }
 
   if (transaction.type === TransactionType.Refund) {
     const fee = Amounts.sub(
       Amounts.parseOrThrow(transaction.amountRaw),
       Amounts.parseOrThrow(transaction.amountEffective),
-    ).amount
-    return <TransactionTemplate>
-      <h2>Refund</h2>
-      <div>{transaction.timestamp.t_ms === 'never' ? 'never' : 
format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')}</div>
-      <br />
-      <Part big title="Total refund" 
text={amountToString(transaction.amountEffective)} kind='positive' />
-      <Part big title="Refund amount" 
text={amountToString(transaction.amountRaw)} kind='neutral' />
-      <Part big title="Fee" text={amountToString(fee)} kind='negative' />
-      <Part title="Merchant" text={transaction.info.merchant.name} 
kind='neutral' />
-      <Part title="Purchase" text={transaction.info.summary} kind='neutral' />
-      <Part title="Receipt" text={`#${transaction.info.orderId}`} 
kind='neutral' />
-
-      <p>
-        {transaction.info.summary}
-      </p>
-      <div>
-        {transaction.info.products && transaction.info.products.length > 0 &&
-          <ListOfProducts>
-            {transaction.info.products.map((p, k) => <RowBorderGray key={k}>
-              <a href="#" onClick={showLargePic}>
-                <img src={p.image ? p.image : emptyImg} />
-              </a>
-              <div>
-                {p.quantity && p.quantity > 0 && <SmallLightText>x 
{p.quantity} {p.unit}</SmallLightText>}
-                <div>{p.description}</div>
-              </div>
-            </RowBorderGray>)}
-          </ListOfProducts>
-        }
-      </div>
-    </TransactionTemplate>
-  }
+    ).amount;
+    return (
+      <TransactionTemplate>
+        <h2>Refund</h2>
+        <div>
+          {transaction.timestamp.t_ms === "never"
+            ? "never"
+            : format(transaction.timestamp.t_ms, "dd MMMM yyyy, HH:mm")}
+        </div>
+        <br />
+        <Part
+          big
+          title="Total refund"
+          text={amountToString(transaction.amountEffective)}
+          kind="positive"
+        />
+        <Part
+          big
+          title="Refund amount"
+          text={amountToString(transaction.amountRaw)}
+          kind="neutral"
+        />
+        <Part big title="Fee" text={amountToString(fee)} kind="negative" />
+        <Part
+          title="Merchant"
+          text={transaction.info.merchant.name}
+          kind="neutral"
+        />
+        <Part title="Purchase" text={transaction.info.summary} kind="neutral" 
/>
+        <Part
+          title="Receipt"
+          text={`#${transaction.info.orderId}`}
+          kind="neutral"
+        />
 
+        <p>{transaction.info.summary}</p>
+        <div>
+          {transaction.info.products && transaction.info.products.length > 0 
&& (
+            <ListOfProducts>
+              {transaction.info.products.map((p, k) => (
+                <RowBorderGray key={k}>
+                  <a href="#" onClick={showLargePic}>
+                    <img src={p.image ? p.image : emptyImg} />
+                  </a>
+                  <div>
+                    {p.quantity && p.quantity > 0 && (
+                      <SmallLightText>
+                        x {p.quantity} {p.unit}
+                      </SmallLightText>
+                    )}
+                    <div>{p.description}</div>
+                  </div>
+                </RowBorderGray>
+              ))}
+            </ListOfProducts>
+          )}
+        </div>
+      </TransactionTemplate>
+    );
+  }
 
-  return <div></div>
+  return <div></div>;
 }
diff --git a/packages/taler-wallet-webextension/src/wallet/Welcome.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/Welcome.stories.tsx
index 6579450b..7e6588fa 100644
--- a/packages/taler-wallet-webextension/src/wallet/Welcome.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Welcome.stories.tsx
@@ -15,16 +15,15 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { createExample } from '../test-utils';
-import { View as TestedComponent } from './Welcome';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
+import { createExample } from "../test-utils";
+import { View as TestedComponent } from "./Welcome";
 
 export default {
-  title: 'wallet/welcome',
+  title: "wallet/welcome",
   component: TestedComponent,
 };
 
@@ -32,11 +31,11 @@ export const Normal = createExample(TestedComponent, {
   permissionsEnabled: true,
   diagnostics: {
     errors: [],
-    walletManifestVersion: '1.0',
-    walletManifestDisplayVersion: '1.0',
+    walletManifestVersion: "1.0",
+    walletManifestDisplayVersion: "1.0",
     firefoxIdbProblem: false,
     dbOutdated: false,
-  }
+  },
 });
 
 export const TimedoutDiagnostics = createExample(TestedComponent, {
@@ -47,4 +46,3 @@ export const TimedoutDiagnostics = 
createExample(TestedComponent, {
 export const RunningDiagnostics = createExample(TestedComponent, {
   permissionsEnabled: false,
 });
-
diff --git a/packages/taler-wallet-webextension/src/wallet/Welcome.tsx 
b/packages/taler-wallet-webextension/src/wallet/Welcome.tsx
index d11070d9..0b8e5c60 100644
--- a/packages/taler-wallet-webextension/src/wallet/Welcome.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Welcome.tsx
@@ -27,43 +27,55 @@ import { Diagnostics } from "../components/Diagnostics";
 import { WalletBox } from "../components/styled";
 import { useDiagnostics } from "../hooks/useDiagnostics";
 import { WalletDiagnostics } from "@gnu-taler/taler-util";
-import { h } from 'preact';
+import { h } from "preact";
 
 export function WelcomePage() {
-  const [permissionsEnabled, togglePermissions] = useExtendedPermissions()
-  const [diagnostics, timedOut] = useDiagnostics()
-  return <View
-    permissionsEnabled={permissionsEnabled} 
togglePermissions={togglePermissions}
-    diagnostics={diagnostics} timedOut={timedOut}
-  />
+  const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
+  const [diagnostics, timedOut] = useDiagnostics();
+  return (
+    <View
+      permissionsEnabled={permissionsEnabled}
+      togglePermissions={togglePermissions}
+      diagnostics={diagnostics}
+      timedOut={timedOut}
+    />
+  );
 }
 
 export interface ViewProps {
-  permissionsEnabled: boolean,
-  togglePermissions: () => void,
-  diagnostics: WalletDiagnostics | undefined,
-  timedOut: boolean,
+  permissionsEnabled: boolean;
+  togglePermissions: () => void;
+  diagnostics: WalletDiagnostics | undefined;
+  timedOut: boolean;
 }
-export function View({ permissionsEnabled, togglePermissions, diagnostics, 
timedOut }: ViewProps): JSX.Element {
-  return (<WalletBox>
-    <h1>Browser Extension Installed!</h1>
-    <div>
-      <p>Thank you for installing the wallet.</p>
-      <Diagnostics diagnostics={diagnostics} timedOut={timedOut} />
-      <h2>Permissions</h2>
-      <Checkbox label="Automatically open wallet based on page content"
-        name="perm"
-        description="(Enabling this option below will make using the wallet 
faster, but requires more permissions from your browser.)"
-        enabled={permissionsEnabled} onToggle={togglePermissions}
-      />
-      <h2>Next Steps</h2>
-      <a href="https://demo.taler.net/"; style={{ display: "block" }}>
-        Try the demo »
-      </a>
-      <a href="https://demo.taler.net/"; style={{ display: "block" }}>
-        Learn how to top up your wallet balance »
-      </a>
-    </div>
-  </WalletBox>
+export function View({
+  permissionsEnabled,
+  togglePermissions,
+  diagnostics,
+  timedOut,
+}: ViewProps): JSX.Element {
+  return (
+    <WalletBox>
+      <h1>Browser Extension Installed!</h1>
+      <div>
+        <p>Thank you for installing the wallet.</p>
+        <Diagnostics diagnostics={diagnostics} timedOut={timedOut} />
+        <h2>Permissions</h2>
+        <Checkbox
+          label="Automatically open wallet based on page content"
+          name="perm"
+          description="(Enabling this option below will make using the wallet 
faster, but requires more permissions from your browser.)"
+          enabled={permissionsEnabled}
+          onToggle={togglePermissions}
+        />
+        <h2>Next Steps</h2>
+        <a href="https://demo.taler.net/"; style={{ display: "block" }}>
+          Try the demo »
+        </a>
+        <a href="https://demo.taler.net/"; style={{ display: "block" }}>
+          Learn how to top up your wallet balance »
+        </a>
+      </div>
+    </WalletBox>
   );
 }
diff --git a/packages/taler-wallet-webextension/src/walletEntryPoint.tsx 
b/packages/taler-wallet-webextension/src/walletEntryPoint.tsx
index 023ee94c..f097d58b 100644
--- a/packages/taler-wallet-webextension/src/walletEntryPoint.tsx
+++ b/packages/taler-wallet-webextension/src/walletEntryPoint.tsx
@@ -21,7 +21,7 @@
  */
 
 import { setupI18n } from "@gnu-taler/taler-util";
-import { createHashHistory } from 'history';
+import { createHashHistory } from "history";
 import { Fragment, h, render } from "preact";
 import Router, { route, Route } from "preact-router";
 import { useEffect } from "preact/hooks";
@@ -29,22 +29,19 @@ import { LogoHeader } from "./components/LogoHeader";
 import { DevContextProvider } from "./context/devContext";
 import { PayPage } from "./cta/Pay";
 import { RefundPage } from "./cta/Refund";
-import { TipPage } from './cta/Tip';
+import { TipPage } from "./cta/Tip";
 import { WithdrawPage } from "./cta/Withdraw";
 import { strings } from "./i18n/strings";
-import {
-  Pages, WalletNavBar
-} from "./NavigationBar";
+import { Pages, WalletNavBar } from "./NavigationBar";
 import { BalancePage } from "./wallet/BalancePage";
 import { HistoryPage } from "./wallet/History";
 import { SettingsPage } from "./wallet/Settings";
-import { TransactionPage } from './wallet/Transaction';
+import { TransactionPage } from "./wallet/Transaction";
 import { WelcomePage } from "./wallet/Welcome";
-import { BackupPage } from './wallet/BackupPage';
+import { BackupPage } from "./wallet/BackupPage";
 import { DeveloperPage } from "./popup/Debug.js";
 import { ManualWithdrawPage } from "./wallet/ManualWithdrawPage.js";
 
-
 function main(): void {
   try {
     const container = document.getElementById("container");
@@ -69,51 +66,86 @@ if (document.readyState === "loading") {
 }
 
 function withLogoAndNavBar(Component: any) {
-  return (props: any) => <Fragment>
-    <LogoHeader />
-    <WalletNavBar />
-    <Component {...props} />
-  </Fragment>
+  return (props: any) => (
+    <Fragment>
+      <LogoHeader />
+      <WalletNavBar />
+      <Component {...props} />
+    </Fragment>
+  );
 }
 
 function Application() {
-  return <div>
-    <DevContextProvider>
-      <Router history={createHashHistory()} >
-
-        <Route path={Pages.welcome} component={withLogoAndNavBar(WelcomePage)} 
/>
-
-        <Route path={Pages.history} component={withLogoAndNavBar(HistoryPage)} 
/>
-        <Route path={Pages.transaction} 
component={withLogoAndNavBar(TransactionPage)} />
-        <Route path={Pages.balance} component={withLogoAndNavBar(BalancePage)} 
-              goToWalletManualWithdraw={() => route(Pages.manual_withdraw)} 
-        />
-        <Route path={Pages.settings} 
component={withLogoAndNavBar(SettingsPage)} />
-        <Route path={Pages.backup} component={withLogoAndNavBar(BackupPage)} />
-
-        <Route path={Pages.manual_withdraw} 
component={withLogoAndNavBar(ManualWithdrawPage)} />
-
-        <Route path={Pages.reset_required} component={() => <div>no yet 
implemented</div>} />
-        <Route path={Pages.payback} component={() => <div>no yet 
implemented</div>} />
-        <Route path={Pages.return_coins} component={() => <div>no yet 
implemented</div>} />
-
-        <Route path={Pages.dev} component={withLogoAndNavBar(DeveloperPage)} />
-
-        {/** call to action */}
-        <Route path={Pages.pay} component={PayPage} />
-        <Route path={Pages.refund} component={RefundPage} />
-        <Route path={Pages.tips} component={TipPage} />
-        <Route path={Pages.withdraw} component={WithdrawPage} />
-
-        <Route default component={Redirect} to={Pages.history} />
-      </Router>
-    </DevContextProvider>
-  </div>
+  return (
+    <div>
+      <DevContextProvider>
+        <Router history={createHashHistory()}>
+          <Route
+            path={Pages.welcome}
+            component={withLogoAndNavBar(WelcomePage)}
+          />
+
+          <Route
+            path={Pages.history}
+            component={withLogoAndNavBar(HistoryPage)}
+          />
+          <Route
+            path={Pages.transaction}
+            component={withLogoAndNavBar(TransactionPage)}
+          />
+          <Route
+            path={Pages.balance}
+            component={withLogoAndNavBar(BalancePage)}
+            goToWalletManualWithdraw={() => route(Pages.manual_withdraw)}
+          />
+          <Route
+            path={Pages.settings}
+            component={withLogoAndNavBar(SettingsPage)}
+          />
+          <Route
+            path={Pages.backup}
+            component={withLogoAndNavBar(BackupPage)}
+          />
+
+          <Route
+            path={Pages.manual_withdraw}
+            component={withLogoAndNavBar(ManualWithdrawPage)}
+          />
+
+          <Route
+            path={Pages.reset_required}
+            component={() => <div>no yet implemented</div>}
+          />
+          <Route
+            path={Pages.payback}
+            component={() => <div>no yet implemented</div>}
+          />
+          <Route
+            path={Pages.return_coins}
+            component={() => <div>no yet implemented</div>}
+          />
+
+          <Route
+            path={Pages.dev}
+            component={withLogoAndNavBar(DeveloperPage)}
+          />
+
+          {/** call to action */}
+          <Route path={Pages.pay} component={PayPage} />
+          <Route path={Pages.refund} component={RefundPage} />
+          <Route path={Pages.tips} component={TipPage} />
+          <Route path={Pages.withdraw} component={WithdrawPage} />
+
+          <Route default component={Redirect} to={Pages.history} />
+        </Router>
+      </DevContextProvider>
+    </div>
+  );
 }
 
 function Redirect({ to }: { to: string }): null {
   useEffect(() => {
-    route(to, true)
-  })
-  return null
+    route(to, true);
+  });
+  return null;
 }
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts 
b/packages/taler-wallet-webextension/src/wxApi.ts
index 92597cbd..90cfd3ed 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -47,7 +47,12 @@ import {
   AddExchangeRequest,
   GetExchangeTosResult,
 } from "@gnu-taler/taler-util";
-import { AddBackupProviderRequest, BackupProviderState, OperationFailedError, 
RemoveBackupProviderRequest } from "@gnu-taler/taler-wallet-core";
+import {
+  AddBackupProviderRequest,
+  BackupProviderState,
+  OperationFailedError,
+  RemoveBackupProviderRequest,
+} from "@gnu-taler/taler-wallet-core";
 import { BackupInfo } from "@gnu-taler/taler-wallet-core";
 import { ExchangeWithdrawDetails } from 
"@gnu-taler/taler-wallet-core/src/operations/withdraw";
 
@@ -149,78 +154,89 @@ interface CurrencyInfo {
   pub: string;
 }
 interface ListOfKnownCurrencies {
-  auditors: CurrencyInfo[],
-  exchanges: CurrencyInfo[],
+  auditors: CurrencyInfo[];
+  exchanges: CurrencyInfo[];
 }
 
 /**
  * Get a list of currencies from known auditors and exchanges
  */
 export function listKnownCurrencies(): Promise<ListOfKnownCurrencies> {
-  return callBackend("listCurrencies", {}).then(result => {
-    console.log("result list", result)
-    const auditors = result.trustedAuditors.map((a: Record<string, string>) => 
({
-      name: a.currency,
-      baseUrl: a.auditorBaseUrl,
-      pub: a.auditorPub,
-    }))
-    const exchanges = result.trustedExchanges.map((a: Record<string, string>) 
=> ({
-      name: a.currency,
-      baseUrl: a.exchangeBaseUrl,
-      pub: a.exchangeMasterPub,
-    }))
-    return { auditors, exchanges }
+  return callBackend("listCurrencies", {}).then((result) => {
+    console.log("result list", result);
+    const auditors = result.trustedAuditors.map(
+      (a: Record<string, string>) => ({
+        name: a.currency,
+        baseUrl: a.auditorBaseUrl,
+        pub: a.auditorPub,
+      }),
+    );
+    const exchanges = result.trustedExchanges.map(
+      (a: Record<string, string>) => ({
+        name: a.currency,
+        baseUrl: a.exchangeBaseUrl,
+        pub: a.exchangeMasterPub,
+      }),
+    );
+    return { auditors, exchanges };
   });
 }
 
 export function listExchanges(): Promise<ExchangesListRespose> {
-  return callBackend("listExchanges", {})
+  return callBackend("listExchanges", {});
 }
 
 /**
  * Get information about the current state of wallet backups.
  */
 export function getBackupInfo(): Promise<BackupInfo> {
-  return callBackend("getBackupInfo", {})
+  return callBackend("getBackupInfo", {});
 }
 
 /**
  * Add a backup provider and activate it
  */
-export function addBackupProvider(backupProviderBaseUrl: string, name: 
string): Promise<void> {
+export function addBackupProvider(
+  backupProviderBaseUrl: string,
+  name: string,
+): Promise<void> {
   return callBackend("addBackupProvider", {
-    backupProviderBaseUrl, activate: true, name
-  } as AddBackupProviderRequest)
+    backupProviderBaseUrl,
+    activate: true,
+    name,
+  } as AddBackupProviderRequest);
 }
 
 export function setWalletDeviceId(walletDeviceId: string): Promise<void> {
   return callBackend("setWalletDeviceId", {
-    walletDeviceId
-  } as SetWalletDeviceIdRequest)
+    walletDeviceId,
+  } as SetWalletDeviceIdRequest);
 }
 
 export function syncAllProviders(): Promise<void> {
-  return callBackend("runBackupCycle", {})
+  return callBackend("runBackupCycle", {});
 }
 
 export function syncOneProvider(url: string): Promise<void> {
-  return callBackend("runBackupCycle", { providers: [url] })
+  return callBackend("runBackupCycle", { providers: [url] });
 }
 export function removeProvider(url: string): Promise<void> {
-  return callBackend("removeBackupProvider", { provider: url } as 
RemoveBackupProviderRequest)
+  return callBackend("removeBackupProvider", {
+    provider: url,
+  } as RemoveBackupProviderRequest);
 }
 export function extendedProvider(url: string): Promise<void> {
-  return callBackend("extendBackupProvider", { provider: url })
+  return callBackend("extendBackupProvider", { provider: url });
 }
 
 /**
  * Retry a transaction
- * @param transactionId 
- * @returns 
+ * @param transactionId
+ * @returns
  */
 export function retryTransaction(transactionId: string): Promise<void> {
   return callBackend("retryTransaction", {
-    transactionId
+    transactionId,
   } as RetryTransactionRequest);
 }
 
@@ -229,7 +245,7 @@ export function retryTransaction(transactionId: string): 
Promise<void> {
  */
 export function deleteTransaction(transactionId: string): Promise<void> {
   return callBackend("deleteTransaction", {
-    transactionId
+    transactionId,
   } as DeleteTransactionRequest);
 }
 
@@ -264,29 +280,30 @@ export function acceptWithdrawal(
 
 /**
  * Create a reserve into the exchange that expect the amount indicated
- * @param exchangeBaseUrl 
- * @param amount 
- * @returns 
+ * @param exchangeBaseUrl
+ * @param amount
+ * @returns
  */
 export function acceptManualWithdrawal(
   exchangeBaseUrl: string,
   amount: string,
 ): Promise<AcceptManualWithdrawalResult> {
   return callBackend("acceptManualWithdrawal", {
-    amount, exchangeBaseUrl
+    amount,
+    exchangeBaseUrl,
   });
 }
 
 export function setExchangeTosAccepted(
   exchangeBaseUrl: string,
-  etag: string | undefined
+  etag: string | undefined,
 ): Promise<void> {
   return callBackend("setExchangeTosAccepted", {
-    exchangeBaseUrl, etag
-  } as AcceptExchangeTosRequest)
+    exchangeBaseUrl,
+    etag,
+  } as AcceptExchangeTosRequest);
 }
 
-
 /**
  * Get diagnostics information
  */
@@ -319,7 +336,6 @@ export function getWithdrawalDetailsForUri(
   return callBackend("getWithdrawalDetailsForUri", req);
 }
 
-
 /**
  * Get diagnostics information
  */
@@ -333,17 +349,15 @@ export function getExchangeTos(
   acceptedFormat: string[],
 ): Promise<GetExchangeTosResult> {
   return callBackend("getExchangeTos", {
-    exchangeBaseUrl, acceptedFormat
+    exchangeBaseUrl,
+    acceptedFormat,
   });
 }
 
-export function addExchange(
-  req: AddExchangeRequest,
-): Promise<void> {
+export function addExchange(req: AddExchangeRequest): Promise<void> {
   return callBackend("addExchange", req);
 }
 
-
 export function prepareTip(req: PrepareTipRequest): Promise<PrepareTipResult> {
   return callBackend("prepareTip", req);
 }
diff --git a/packages/taler-wallet-webextension/tsconfig.json 
b/packages/taler-wallet-webextension/tsconfig.json
index cff3d885..25920a12 100644
--- a/packages/taler-wallet-webextension/tsconfig.json
+++ b/packages/taler-wallet-webextension/tsconfig.json
@@ -1,9 +1,13 @@
 {
   "compilerOptions": {
     "composite": true,
-    "lib": ["es6", "DOM"],
-    "jsx": "react-jsx",
-    "jsxImportSource": "preact",
+    "lib": [
+      "es6",
+      "DOM"
+    ],
+    "jsx": "react", /* Specify JSX code generation: 'preserve', 
'react-native', or 'react'. */
+    "jsxFactory": "h", /* Specify the JSX factory function to use when 
targeting react JSX emit, e.g. React.createElement or h. */
+    "jsxFragmentFactory": "Fragment", // 
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#custom-jsx-factories
     "moduleResolution": "Node",
     "module": "ESNext",
     "target": "ES6",
@@ -16,7 +20,9 @@
     "esModuleInterop": true,
     "importHelpers": true,
     "rootDir": "./src",
-    "typeRoots": ["./node_modules/@types"]
+    "typeRoots": [
+      "./node_modules/@types"
+    ]
   },
   "references": [
     {
@@ -26,5 +32,7 @@
       "path": "../taler-util/"
     }
   ],
-  "include": ["src/**/*"]
-}
+  "include": [
+    "src/**/*"
+  ]
+}
\ No newline at end of file

-- 
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]