gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 01/08: wip


From: gnunet
Subject: [taler-wallet-core] 01/08: wip
Date: Tue, 26 Mar 2024 20:58:48 +0100

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

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

commit 8aa9ce6d20b41b7eb9b438a56ccd34cb0da35f80
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Thu Mar 21 12:11:31 2024 -0300

    wip
---
 packages/bank-ui/src/Routing.tsx                   |  11 +-
 packages/bank-ui/src/app.tsx                       |  92 +++++-
 packages/bank-ui/src/components/Cashouts/index.ts  |   3 +-
 packages/bank-ui/src/components/Cashouts/test.ts   |   2 +-
 .../bank-ui/src/components/Transactions/index.ts   |  26 +-
 .../bank-ui/src/components/Transactions/views.tsx  |   5 +-
 packages/bank-ui/src/context/config.ts             |   2 +-
 packages/bank-ui/src/hooks/account.ts              |  12 +-
 packages/bank-ui/src/hooks/bank-state.ts           |   2 +-
 packages/bank-ui/src/hooks/regional.ts             |  26 +-
 packages/bank-ui/src/hooks/session.ts              |   2 +-
 packages/bank-ui/src/pages/AccountPage/index.ts    |   2 +-
 packages/bank-ui/src/pages/AccountPage/views.tsx   |   2 +-
 packages/bank-ui/src/pages/BankFrame.tsx           |  12 +-
 packages/bank-ui/src/pages/LoginForm.tsx           |  44 +--
 packages/bank-ui/src/pages/OperationState/index.ts |  18 +-
 packages/bank-ui/src/pages/OperationState/state.ts |  10 +-
 .../bank-ui/src/pages/OperationState/views.tsx     |   2 +-
 packages/bank-ui/src/pages/PaymentOptions.tsx      |   2 +-
 .../bank-ui/src/pages/PaytoWireTransferForm.tsx    |   6 +-
 packages/bank-ui/src/pages/ProfileNavigation.tsx   |   7 +-
 packages/bank-ui/src/pages/QrCodeSection.tsx       |   6 +-
 packages/bank-ui/src/pages/RegistrationPage.tsx    |   6 +-
 packages/bank-ui/src/pages/SolveChallengePage.tsx  |   8 +-
 packages/bank-ui/src/pages/WalletWithdrawForm.tsx  |  20 +-
 packages/bank-ui/src/pages/WireTransfer.tsx        |   2 +-
 .../src/pages/WithdrawalConfirmationQuestion.tsx   |   6 +-
 .../bank-ui/src/pages/WithdrawalOperationPage.tsx  |   6 +-
 packages/bank-ui/src/pages/WithdrawalQRCode.tsx    |   2 +-
 .../src/pages/account/CashoutListForAccount.tsx    |   2 +-
 .../src/pages/account/ShowAccountDetails.tsx       |   6 +-
 .../src/pages/account/UpdateAccountPassword.tsx    |   6 +-
 packages/bank-ui/src/pages/admin/AccountForm.tsx   | 147 +--------
 packages/bank-ui/src/pages/admin/AccountList.tsx   |   4 +-
 packages/bank-ui/src/pages/admin/AdminHome.tsx     |  12 +-
 .../bank-ui/src/pages/admin/CreateNewAccount.tsx   |   6 +-
 packages/bank-ui/src/pages/admin/DownloadStats.tsx |  12 +-
 packages/bank-ui/src/pages/admin/RemoveAccount.tsx |   6 +-
 .../src/pages/regional/ConversionConfig.tsx        |  10 +-
 .../bank-ui/src/pages/regional/CreateCashout.tsx   | 159 +---------
 .../src/pages/regional/ShowCashoutDetails.tsx      |   4 +-
 packages/bank-ui/src/settings.ts                   |   9 +-
 packages/bank-ui/src/stories.test.ts               |   9 +-
 packages/merchant-backoffice-ui/copyleft-header.js |   2 +-
 .../merchant-backoffice-ui/src/AdminRoutes.tsx     |   4 +-
 .../merchant-backoffice-ui/src/Application.tsx     | 225 ++++++--------
 .../src/ApplicationReadyRoutes.tsx                 |   8 +-
 .../src/{InstanceRoutes.tsx => Rounting.tsx}       | 261 ++++++++--------
 .../src/components/exception/AsyncButton.tsx       |   2 +-
 .../src/components/exception/QR.tsx                |   2 +-
 .../src/components/exception/loading.tsx           |   2 +-
 .../src/components/form/FormProvider.tsx           |   2 +-
 .../src/components/form/Input.tsx                  |   2 +-
 .../src/components/form/InputArray.tsx             |   2 +-
 .../src/components/form/InputBoolean.tsx           |   2 +-
 .../src/components/form/InputCurrency.tsx          |   2 +-
 .../src/components/form/InputDate.tsx              |   6 +-
 .../src/components/form/InputDuration.tsx          |   2 +-
 .../src/components/form/InputGroup.tsx             |   2 +-
 .../src/components/form/InputImage.tsx             |   2 +-
 .../src/components/form/InputLocation.tsx          |   2 +-
 .../src/components/form/InputNumber.tsx            |   2 +-
 .../src/components/form/InputPayto.tsx             |   2 +-
 .../src/components/form/InputPaytoForm.stories.tsx |   2 +-
 .../src/components/form/InputPaytoForm.tsx         |   2 +-
 .../src/components/form/InputSearchOnList.tsx      |   2 +-
 .../src/components/form/InputSecured.stories.tsx   |   2 +-
 .../src/components/form/InputSecured.tsx           |   2 +-
 .../src/components/form/InputSelector.tsx          |   2 +-
 .../src/components/form/InputStock.stories.tsx     |   2 +-
 .../src/components/form/InputStock.tsx             |   2 +-
 .../src/components/form/InputTab.tsx               |   2 +-
 .../src/components/form/InputTaxes.tsx             |   2 +-
 .../src/components/form/InputToggle.tsx            |   2 +-
 .../src/components/form/InputWithAddon.tsx         |   2 +-
 .../src/components/form/TextField.tsx              |   2 +-
 .../src/components/form/useField.tsx               |   2 +-
 .../src/components/form/useGroupField.tsx          |   2 +-
 .../src/components/index.stories.ts                |   2 +-
 .../instance/DefaultInstanceFormFields.tsx         |   2 +-
 .../src/components/menu/LangSelector.tsx           |   2 +-
 .../src/components/menu/NavigationBar.tsx          |   2 +-
 .../src/components/menu/SideBar.tsx                |   2 +-
 .../src/components/menu/index.tsx                  |   7 +-
 .../src/components/modal/index.tsx                 |   2 +-
 .../notifications/CreatedSuccessfully.tsx          |   2 +-
 .../notifications/Notifications.stories.tsx        |   2 +-
 .../src/components/notifications/index.tsx         |   2 +-
 .../src/components/picker/DatePicker.tsx           |   2 +-
 .../components/picker/DurationPicker.stories.tsx   |   2 +-
 .../src/components/picker/DurationPicker.tsx       |   2 +-
 .../product/InventoryProductForm.stories.tsx       |   2 +-
 .../components/product/InventoryProductForm.tsx    |   2 +-
 .../components/product/NonInventoryProductForm.tsx |   2 +-
 .../src/components/product/ProductForm.tsx         |   2 +-
 .../src/components/product/ProductList.tsx         |   2 +-
 .../src/context/backend.test.ts                    |   2 +-
 .../merchant-backoffice-ui/src/context/backend.ts  |   6 +-
 .../merchant-backoffice-ui/src/context/config.ts   |   2 +-
 .../merchant-backoffice-ui/src/context/instance.ts |   6 +-
 .../src/context/{instance.ts => settings.ts}       |  40 ++-
 packages/merchant-backoffice-ui/src/custom.d.ts    |   2 +-
 .../merchant-backoffice-ui/src/declaration.d.ts    |   2 +-
 packages/merchant-backoffice-ui/src/hooks/async.ts |   2 +-
 .../merchant-backoffice-ui/src/hooks/backend.ts    |   2 +-
 packages/merchant-backoffice-ui/src/hooks/bank.ts  |   2 +-
 packages/merchant-backoffice-ui/src/hooks/index.ts |  15 +-
 .../src/hooks/instance.test.ts                     |   2 +-
 .../merchant-backoffice-ui/src/hooks/instance.ts   |   2 +-
 .../merchant-backoffice-ui/src/hooks/listener.ts   |   2 +-
 .../merchant-backoffice-ui/src/hooks/merchant.ts   |   2 +-
 .../src/hooks/notifications.ts                     |   2 +-
 .../merchant-backoffice-ui/src/hooks/order.test.ts |   2 +-
 packages/merchant-backoffice-ui/src/hooks/order.ts |   2 +-
 packages/merchant-backoffice-ui/src/hooks/otp.ts   |   2 +-
 .../merchant-backoffice-ui/src/hooks/preference.ts |  85 ++++++
 .../src/hooks/product.test.ts                      |   2 +-
 .../merchant-backoffice-ui/src/hooks/product.ts    |   2 +-
 .../src/hooks/reserve.test.ts                      |   2 +-
 .../merchant-backoffice-ui/src/hooks/reserves.ts   |   2 +-
 .../merchant-backoffice-ui/src/hooks/session.ts    | 185 +++++++++++
 .../merchant-backoffice-ui/src/hooks/templates.ts  |   2 +-
 .../merchant-backoffice-ui/src/hooks/testing.tsx   |   2 +-
 .../src/hooks/transfer.test.ts                     |   2 +-
 .../merchant-backoffice-ui/src/hooks/transfer.ts   |   2 +-
 packages/merchant-backoffice-ui/src/hooks/urls.ts  |   2 +-
 .../src/hooks/useSettings.ts                       |  73 -----
 .../merchant-backoffice-ui/src/hooks/webhooks.ts   |   2 +-
 packages/merchant-backoffice-ui/src/index.html     |   2 +-
 packages/merchant-backoffice-ui/src/index.tsx      |   8 +-
 .../src/paths/admin/create/Create.stories.tsx      |   2 +-
 .../src/paths/admin/create/CreatePage.tsx          |   2 +-
 .../admin/create/InstanceCreatedSuccessfully.tsx   |   2 +-
 .../src/paths/admin/create/index.tsx               |   2 +-
 .../src/paths/admin/create/stories.tsx             |   2 +-
 .../src/paths/admin/index.stories.ts               |   2 +-
 .../src/paths/admin/list/TableActive.tsx           |   2 +-
 .../src/paths/admin/list/View.stories.tsx          |   2 +-
 .../src/paths/admin/list/View.tsx                  |   2 +-
 .../src/paths/admin/list/index.tsx                 |   2 +-
 .../instance/accounts/create/Create.stories.tsx    |   2 +-
 .../paths/instance/accounts/create/CreatePage.tsx  |   2 +-
 .../src/paths/instance/accounts/create/index.tsx   |   2 +-
 .../paths/instance/accounts/list/List.stories.tsx  |   2 +-
 .../src/paths/instance/accounts/list/ListPage.tsx  |   2 +-
 .../src/paths/instance/accounts/list/Table.tsx     |   2 +-
 .../src/paths/instance/accounts/list/index.tsx     |   2 +-
 .../instance/accounts/update/Update.stories.tsx    |   2 +-
 .../paths/instance/accounts/update/UpdatePage.tsx  |   2 +-
 .../src/paths/instance/accounts/update/index.tsx   |   2 +-
 .../src/paths/instance/details/DetailPage.tsx      |   2 +-
 .../src/paths/instance/details/index.tsx           |   2 +-
 .../src/paths/instance/details/stories.tsx         |   2 +-
 .../src/paths/instance/index.stories.ts            |   2 +-
 .../paths/instance/kyc/list/ListPage.stories.tsx   |   2 +-
 .../src/paths/instance/kyc/list/ListPage.tsx       |   2 +-
 .../src/paths/instance/kyc/list/index.tsx          |   2 +-
 .../instance/orders/create/Create.stories.tsx      |   2 +-
 .../paths/instance/orders/create/CreatePage.tsx    |   6 +-
 .../orders/create/OrderCreatedSuccessfully.tsx     |   2 +-
 .../src/paths/instance/orders/create/index.tsx     |   2 +-
 .../instance/orders/details/Detail.stories.tsx     |   2 +-
 .../paths/instance/orders/details/DetailPage.tsx   |  16 +-
 .../src/paths/instance/orders/details/Timeline.tsx |   6 +-
 .../src/paths/instance/orders/details/index.tsx    |   2 +-
 .../paths/instance/orders/list/List.stories.tsx    |   2 +-
 .../src/paths/instance/orders/list/ListPage.tsx    |   6 +-
 .../src/paths/instance/orders/list/Table.tsx       |   8 +-
 .../src/paths/instance/orders/list/index.tsx       |   2 +-
 .../instance/otp_devices/create/Create.stories.tsx |   2 +-
 .../instance/otp_devices/create/CreatePage.tsx     |   2 +-
 .../otp_devices/create/CreatedSuccessfully.tsx     |   2 +-
 .../paths/instance/otp_devices/create/index.tsx    |   2 +-
 .../instance/otp_devices/list/List.stories.tsx     |   2 +-
 .../paths/instance/otp_devices/list/ListPage.tsx   |   2 +-
 .../src/paths/instance/otp_devices/list/Table.tsx  |   2 +-
 .../src/paths/instance/otp_devices/list/index.tsx  |   2 +-
 .../instance/otp_devices/update/Update.stories.tsx |   2 +-
 .../instance/otp_devices/update/UpdatePage.tsx     |   2 +-
 .../paths/instance/otp_devices/update/index.tsx    |   2 +-
 .../instance/products/create/Create.stories.tsx    |   2 +-
 .../paths/instance/products/create/CreatePage.tsx  |   2 +-
 .../products/create/CreatedSuccessfully.tsx        |   2 +-
 .../src/paths/instance/products/create/index.tsx   |   2 +-
 .../paths/instance/products/list/List.stories.tsx  |   2 +-
 .../src/paths/instance/products/list/Table.tsx     |   6 +-
 .../src/paths/instance/products/list/index.tsx     |   2 +-
 .../instance/products/update/Update.stories.tsx    |   2 +-
 .../paths/instance/products/update/UpdatePage.tsx  |   2 +-
 .../src/paths/instance/products/update/index.tsx   |   2 +-
 .../instance/templates/create/Create.stories.tsx   |   2 +-
 .../paths/instance/templates/create/CreatePage.tsx |   2 +-
 .../src/paths/instance/templates/create/index.tsx  |   2 +-
 .../paths/instance/templates/list/List.stories.tsx |   2 +-
 .../src/paths/instance/templates/list/ListPage.tsx |   2 +-
 .../src/paths/instance/templates/list/Table.tsx    |   2 +-
 .../src/paths/instance/templates/list/index.tsx    |   2 +-
 .../src/paths/instance/templates/qr/Qr.stories.tsx |   2 +-
 .../src/paths/instance/templates/qr/QrPage.tsx     |   2 +-
 .../src/paths/instance/templates/qr/index.tsx      |   2 +-
 .../instance/templates/update/Update.stories.tsx   |   2 +-
 .../paths/instance/templates/update/UpdatePage.tsx |   2 +-
 .../src/paths/instance/templates/update/index.tsx  |   2 +-
 .../paths/instance/templates/use/Use.stories.tsx   |   2 +-
 .../src/paths/instance/templates/use/UsePage.tsx   |   2 +-
 .../src/paths/instance/templates/use/index.tsx     |   2 +-
 .../src/paths/instance/token/DetailPage.tsx        |   2 +-
 .../src/paths/instance/token/index.tsx             |   2 +-
 .../src/paths/instance/token/stories.tsx           |   2 +-
 .../instance/transfers/create/Create.stories.tsx   |   2 +-
 .../paths/instance/transfers/create/CreatePage.tsx |   2 +-
 .../src/paths/instance/transfers/create/index.tsx  |   2 +-
 .../paths/instance/transfers/list/List.stories.tsx |   2 +-
 .../src/paths/instance/transfers/list/ListPage.tsx |   2 +-
 .../src/paths/instance/transfers/list/Table.tsx    |   6 +-
 .../src/paths/instance/transfers/list/index.tsx    |   2 +-
 .../src/paths/instance/transfers/update/index.tsx  |   2 +-
 .../src/paths/instance/update/Update.stories.tsx   |   2 +-
 .../src/paths/instance/update/UpdatePage.tsx       |   2 +-
 .../src/paths/instance/update/index.tsx            |   2 +-
 .../instance/webhooks/create/Create.stories.tsx    |   2 +-
 .../paths/instance/webhooks/create/CreatePage.tsx  |   2 +-
 .../src/paths/instance/webhooks/create/index.tsx   |   2 +-
 .../paths/instance/webhooks/list/List.stories.tsx  |   2 +-
 .../src/paths/instance/webhooks/list/ListPage.tsx  |   2 +-
 .../src/paths/instance/webhooks/list/Table.tsx     |   2 +-
 .../src/paths/instance/webhooks/list/index.tsx     |   2 +-
 .../instance/webhooks/update/Update.stories.tsx    |   2 +-
 .../paths/instance/webhooks/update/UpdatePage.tsx  |   2 +-
 .../src/paths/instance/webhooks/update/index.tsx   |   2 +-
 .../src/paths/login/index.tsx                      | 339 +++++++++++----------
 .../src/paths/notfound/index.tsx                   |   2 +-
 .../src/paths/settings/index.tsx                   |   4 +-
 .../merchant-backoffice-ui/src/schemas/index.ts    |   2 +-
 .../merchant-backoffice-ui/src/scss/_aside.scss    |   2 +-
 .../merchant-backoffice-ui/src/scss/_card.scss     |   2 +-
 .../src/scss/_custom-calendar.scss                 |   2 +-
 .../merchant-backoffice-ui/src/scss/_footer.scss   |   2 +-
 .../merchant-backoffice-ui/src/scss/_form.scss     |   2 +-
 .../merchant-backoffice-ui/src/scss/_hero-bar.scss |   2 +-
 .../merchant-backoffice-ui/src/scss/_loading.scss  |   2 +-
 .../src/scss/_main-section.scss                    |   2 +-
 .../merchant-backoffice-ui/src/scss/_misc.scss     |   2 +-
 .../merchant-backoffice-ui/src/scss/_modal.scss    |   2 +-
 .../merchant-backoffice-ui/src/scss/_nav-bar.scss  |   2 +-
 .../merchant-backoffice-ui/src/scss/_table.scss    |   2 +-
 .../src/scss/_theme-default.scss                   |   2 +-
 .../merchant-backoffice-ui/src/scss/_tiles.scss    |   2 +-
 .../src/scss/_title-bar.scss                       |   2 +-
 .../src/scss/fonts/nunito.css                      |   2 +-
 .../merchant-backoffice-ui/src/scss/libs/_all.scss |   2 +-
 packages/merchant-backoffice-ui/src/scss/main.scss |   2 +-
 .../src/settings.ts                                |  61 ++--
 .../merchant-backoffice-ui/src/stories.test.ts     |   2 +-
 packages/merchant-backoffice-ui/src/stories.tsx    |   2 +-
 packages/merchant-backoffice-ui/src/sw.js          |   2 +-
 .../merchant-backoffice-ui/src/utils/amount.ts     |   2 +-
 .../merchant-backoffice-ui/src/utils/constants.ts  |   4 +-
 .../merchant-backoffice-ui/src/utils/regex.test.ts |   2 +-
 packages/merchant-backoffice-ui/src/utils/table.ts |   2 +-
 packages/merchant-backoffice-ui/src/utils/types.ts |   2 +-
 packages/taler-util/src/http-client/bank-core.ts   |   2 +-
 packages/taler-util/src/http-client/merchant.ts    |  54 ++--
 packages/taler-util/src/index.ts                   |   1 +
 packages/web-util/src/context/activity.ts          |  65 ++++
 packages/web-util/src/context/bank-api.ts          | 202 ++++++++++++
 packages/web-util/src/context/index.ts             |   5 +-
 packages/web-util/src/context/merchant-api.ts      | 226 ++++++++++++++
 packages/web-util/src/context/navigation.ts        | 102 +++++++
 .../web-util/src/context/wallet-integration.ts     |  83 +++++
 packages/web-util/src/index.browser.ts             |   1 +
 packages/web-util/src/utils/route.ts               | 129 ++++++++
 272 files changed, 2110 insertions(+), 1273 deletions(-)

diff --git a/packages/bank-ui/src/Routing.tsx b/packages/bank-ui/src/Routing.tsx
index fbf5aa9ec..489dbe30b 100644
--- a/packages/bank-ui/src/Routing.tsx
+++ b/packages/bank-ui/src/Routing.tsx
@@ -16,7 +16,11 @@
 
 import {
   LocalNotificationBanner,
+  urlPattern,
+  useBankCoreApiContext,
+  useCurrentLocation,
   useLocalNotification,
+  useNavigationContext,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
@@ -29,8 +33,6 @@ import {
   assertUnreachable,
 } from "@gnu-taler/taler-util";
 import { useEffect } from "preact/hooks";
-import { useBankCoreApiContext } from "./context/config.js";
-import { useNavigationContext } from "./context/navigation.js";
 import { useSessionState } from "./hooks/session.js";
 import { AccountPage } from "./pages/AccountPage/index.js";
 import { BankFrame } from "./pages/BankFrame.js";
@@ -51,7 +53,6 @@ import { RemoveAccount } from 
"./pages/admin/RemoveAccount.js";
 import { ConversionConfig } from "./pages/regional/ConversionConfig.js";
 import { CreateCashout } from "./pages/regional/CreateCashout.js";
 import { ShowCashoutDetails } from "./pages/regional/ShowCashoutDetails.js";
-import { urlPattern, useCurrentLocation } from "./route.js";
 
 export function Routing(): VNode {
   const session = useSessionState();
@@ -97,7 +98,7 @@ function PublicRounting({
   const { i18n } = useTranslationContext();
   const location = useCurrentLocation(publicPages);
   const { navigateTo } = useNavigationContext();
-  const { config, authenticator } = useBankCoreApiContext();
+  const { config, lib } = useBankCoreApiContext();
   const [notification, notify, handleError] = useLocalNotification();
 
   useEffect(() => {
@@ -112,7 +113,7 @@ function PublicRounting({
 
   async function doAutomaticLogin(username: string, password: string) {
     await handleError(async () => {
-      const resp = await authenticator(username).createAccessToken(password, {
+      const resp = await lib.auth(username).createAccessToken(password, {
         scope: "readwrite",
         duration: { d_us: "forever" },
         refreshable: true,
diff --git a/packages/bank-ui/src/app.tsx b/packages/bank-ui/src/app.tsx
index 893942059..434c132ed 100644
--- a/packages/bank-ui/src/app.tsx
+++ b/packages/bank-ui/src/app.tsx
@@ -15,22 +15,28 @@
  */
 
 import {
+  CacheEvictor,
+  TalerBankConversionCacheEviction,
+  TalerCoreBankCacheEviction,
+  assertUnreachable,
   canonicalizeBaseUrl,
   getGlobalLogLevel,
   setGlobalLogLevelFromString,
 } from "@gnu-taler/taler-util";
-import { Loading, TranslationProvider } from "@gnu-taler/web-util/browser";
+import { BankApiProvider, BrowserHashNavigationProvider, Loading, 
TalerWalletIntegrationBrowserProvider, TranslationProvider } from 
"@gnu-taler/web-util/browser";
 import { h } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import { SWRConfig } from "swr";
 import { Routing } from "./Routing.js";
-import { BankCoreApiProvider } from "./context/config.js";
-import { BrowserHashNavigationProvider } from "./context/navigation.js";
+// import { BankCoreApiProvider } from "./context/config.js";
+// import { BrowserHashNavigationProvider } from "./context/navigation.js";
 import { SettingsProvider } from "./context/settings.js";
-import { TalerWalletIntegrationBrowserProvider } from 
"./context/wallet-integration.js";
+// import { TalerWalletIntegrationBrowserProvider } from 
"./context/wallet-integration.js";
 import { strings } from "./i18n/strings.js";
 import { BankFrame } from "./pages/BankFrame.js";
 import { BankUiSettings, fetchSettings } from "./settings.js";
+import { revalidateAccountDetails, revalidatePublicAccounts, 
revalidateTransactions } from "./hooks/account.js";
+import { revalidateBusinessAccounts, revalidateCashouts, 
revalidateConversionInfo } from "./hooks/regional.js";
 const WITH_LOCAL_STORAGE_CACHE = false;
 
 export function App() {
@@ -50,7 +56,10 @@ export function App() {
           de: strings["de"].completeness,
         }}
       >
-        <BankCoreApiProvider baseUrl={baseUrl} frameOnError={BankFrame}>
+        <BankApiProvider baseUrl={new URL("/", baseUrl)} 
frameOnError={BankFrame} evictors={{
+          bank: evictBankSwrCache,
+          conversion: evictConversionSwrCache,
+        }}>
           <SWRConfig
             value={{
               provider: WITH_LOCAL_STORAGE_CACHE
@@ -84,7 +93,7 @@ export function App() {
               </BrowserHashNavigationProvider>
             </TalerWalletIntegrationBrowserProvider>
           </SWRConfig>
-        </BankCoreApiProvider>
+        </BankApiProvider>
       </TranslationProvider>
     </SettingsProvider>
   );
@@ -135,3 +144,74 @@ function getInitialBackendBaseURL(
     return canonicalizeBaseUrl(window.origin);
   }
 }
+
+
+const evictBankSwrCache: CacheEvictor<TalerCoreBankCacheEviction> = {
+  async notifySuccess(op) {
+    switch (op) {
+      case TalerCoreBankCacheEviction.DELETE_ACCOUNT: {
+        await Promise.all([
+          revalidatePublicAccounts(),
+          revalidateBusinessAccounts(),
+        ]);
+        return;
+      }
+      case TalerCoreBankCacheEviction.CREATE_ACCOUNT: {
+        // admin balance change on new account
+        await Promise.all([
+          revalidateAccountDetails(),
+          revalidateTransactions(),
+          revalidatePublicAccounts(),
+          revalidateBusinessAccounts(),
+        ]);
+        return;
+      }
+      case TalerCoreBankCacheEviction.UPDATE_ACCOUNT: {
+        await Promise.all([revalidateAccountDetails()]);
+        return;
+      }
+      case TalerCoreBankCacheEviction.CREATE_TRANSACTION: {
+        await Promise.all([
+          revalidateAccountDetails(),
+          revalidateTransactions(),
+        ]);
+        return;
+      }
+      case TalerCoreBankCacheEviction.CONFIRM_WITHDRAWAL: {
+        await Promise.all([
+          revalidateAccountDetails(),
+          revalidateTransactions(),
+        ]);
+        return;
+      }
+      case TalerCoreBankCacheEviction.CREATE_CASHOUT: {
+        await Promise.all([
+          revalidateAccountDetails(),
+          revalidateCashouts(),
+          revalidateTransactions(),
+        ]);
+        return;
+      }
+      case TalerCoreBankCacheEviction.UPDATE_PASSWORD:
+      case TalerCoreBankCacheEviction.ABORT_WITHDRAWAL:
+      case TalerCoreBankCacheEviction.CREATE_WITHDRAWAL:
+        return;
+      default:
+        assertUnreachable(op);
+    }
+  },
+};
+
+const evictConversionSwrCache: CacheEvictor<TalerBankConversionCacheEviction> =
+{
+  async notifySuccess(op) {
+    switch (op) {
+      case TalerBankConversionCacheEviction.UPDATE_RATE: {
+        await revalidateConversionInfo();
+        return;
+      }
+      default:
+        assertUnreachable(op);
+    }
+  },
+};
diff --git a/packages/bank-ui/src/components/Cashouts/index.ts 
b/packages/bank-ui/src/components/Cashouts/index.ts
index 2c6bf681c..99a946865 100644
--- a/packages/bank-ui/src/components/Cashouts/index.ts
+++ b/packages/bank-ui/src/components/Cashouts/index.ts
@@ -14,7 +14,7 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { Loading, utils } from "@gnu-taler/web-util/browser";
+import { Loading, RouteDefinition, utils } from "@gnu-taler/web-util/browser";
 import {
   AbsoluteTime,
   AmountJson,
@@ -25,7 +25,6 @@ import {
 import { ErrorLoadingWithDebug } from "../ErrorLoadingWithDebug.js";
 import { useComponentState } from "./state.js";
 import { FailedView, ReadyView } from "./views.js";
-import { RouteDefinition } from "../../route.js";
 
 export interface Props {
   account: string;
diff --git a/packages/bank-ui/src/components/Cashouts/test.ts 
b/packages/bank-ui/src/components/Cashouts/test.ts
index 4bd6b5eac..4ed0d7c11 100644
--- a/packages/bank-ui/src/components/Cashouts/test.ts
+++ b/packages/bank-ui/src/components/Cashouts/test.ts
@@ -24,7 +24,7 @@ import { SwrMockEnvironment } from 
"@gnu-taler/web-util/testing";
 import { expect } from "chai";
 import { Props } from "./index.js";
 import { useComponentState } from "./state.js";
-import { buildNullRoutDefinition } from "../../route.js";
+import { buildNullRoutDefinition } from "@gnu-taler/web-util/browser";
 
 describe("Cashout states", () => {
   it.skip("should query backend and render transactions", async () => {
diff --git a/packages/bank-ui/src/components/Transactions/index.ts 
b/packages/bank-ui/src/components/Transactions/index.ts
index 4cad6f306..2f68b2ded 100644
--- a/packages/bank-ui/src/components/Transactions/index.ts
+++ b/packages/bank-ui/src/components/Transactions/index.ts
@@ -19,17 +19,17 @@ import { Loading, utils } from 
"@gnu-taler/web-util/browser";
 import { ErrorLoadingWithDebug } from "../ErrorLoadingWithDebug.js";
 import { useComponentState } from "./state.js";
 import { ReadyView } from "./views.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 
 export interface Props {
   account: string;
   routeCreateWireTransfer:
-    | RouteDefinition<{
-        account?: string;
-        subject?: string;
-        amount?: string;
-      }>
-    | undefined;
+  | RouteDefinition<{
+    account?: string;
+    subject?: string;
+    amount?: string;
+  }>
+  | undefined;
 }
 
 export type State = State.Loading | State.LoadingUriError | State.Ready;
@@ -52,12 +52,12 @@ export namespace State {
     status: "ready";
     error: undefined;
     routeCreateWireTransfer:
-      | RouteDefinition<{
-          account?: string;
-          subject?: string;
-          amount?: string;
-        }>
-      | undefined;
+    | RouteDefinition<{
+      account?: string;
+      subject?: string;
+      amount?: string;
+    }>
+    | undefined;
     transactions: Transaction[];
     onGoStart?: () => void;
     onGoNext?: () => void;
diff --git a/packages/bank-ui/src/components/Transactions/views.tsx 
b/packages/bank-ui/src/components/Transactions/views.tsx
index 4397651e2..ebce00a2a 100644
--- a/packages/bank-ui/src/components/Transactions/views.tsx
+++ b/packages/bank-ui/src/components/Transactions/views.tsx
@@ -14,10 +14,9 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { Attention, useTranslationContext } from "@gnu-taler/web-util/browser";
+import { Attention, useBankCoreApiContext, useTranslationContext } from 
"@gnu-taler/web-util/browser";
 import { format } from "date-fns";
 import { Fragment, VNode, h } from "preact";
-import { useBankCoreApiContext } from "../../context/config.js";
 import { RenderAmount } from "../../pages/PaytoWireTransferForm.js";
 import { Time } from "../Time.js";
 import { State } from "./index.js";
@@ -120,7 +119,7 @@ export function ReadyView({
                             <Time
                               format="HH:mm:ss"
                               timestamp={item.when}
-                              // relative={Duration.fromSpec({ days: 1 })}
+                            // relative={Duration.fromSpec({ days: 1 })}
                             />
                           </div>
                           <dl class="font-normal sm:hidden">
diff --git a/packages/bank-ui/src/context/config.ts 
b/packages/bank-ui/src/context/config.ts
index f8be80a6c..55b21d0da 100644
--- a/packages/bank-ui/src/context/config.ts
+++ b/packages/bank-ui/src/context/config.ts
@@ -251,7 +251,7 @@ export const BankCoreApiProviderTesting = ({
 const evictBankSwrCache: CacheEvictor<TalerCoreBankCacheEviction> = {
   async notifySuccess(op) {
     switch (op) {
-      case TalerCoreBankCacheEviction.DELELE_ACCOUNT: {
+      case TalerCoreBankCacheEviction.DELETE_ACCOUNT: {
         await Promise.all([
           revalidatePublicAccounts(),
           revalidateBusinessAccounts(),
diff --git a/packages/bank-ui/src/hooks/account.ts 
b/packages/bank-ui/src/hooks/account.ts
index 5fe12573c..24309183f 100644
--- a/packages/bank-ui/src/hooks/account.ts
+++ b/packages/bank-ui/src/hooks/account.ts
@@ -26,7 +26,7 @@ import { useSessionState } from "./session.js";
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
 import _useSWR, { SWRHook, mutate } from "swr";
-import { useBankCoreApiContext } from "../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 const useSWR = _useSWR as unknown as SWRHook;
 
 export interface InstanceTemplateFilter {
@@ -44,7 +44,7 @@ export function revalidateAccountDetails() {
 
 export function useAccountDetails(account: string) {
   const { state: credentials } = useSessionState();
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
 
   async function fetcher([username, token]: [string, AccessToken]) {
     return await api.getAccount({ username, token });
@@ -70,7 +70,7 @@ export function revalidateWithdrawalDetails() {
 }
 
 export function useWithdrawalDetails(wid: string) {
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
   const [latestStatus, setLatestStatus] = 
useState<WithdrawalOperationStatus>();
 
   async function fetcher([wid, old_state]: [
@@ -123,7 +123,7 @@ export function useTransactionDetails(account: string, tid: 
number) {
   const { state: credentials } = useSessionState();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
 
   async function fetcher([username, token, txid]: [
     string,
@@ -166,7 +166,7 @@ export function usePublicAccounts(
 ) {
   const [offset, setOffset] = useState<number | undefined>(initial);
 
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
 
   async function fetcher([account, txid]: [
     string | undefined,
@@ -242,7 +242,7 @@ export function useTransactions(account: string, initial?: 
number) {
     credentials.status !== "loggedIn" ? undefined : credentials.token;
 
   const [offset, setOffset] = useState<number | undefined>(initial);
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
 
   async function fetcher([username, token, txid]: [
     string,
diff --git a/packages/bank-ui/src/hooks/bank-state.ts 
b/packages/bank-ui/src/hooks/bank-state.ts
index 1d8c4f9e6..616678ddc 100644
--- a/packages/bank-ui/src/hooks/bank-state.ts
+++ b/packages/bank-ui/src/hooks/bank-state.ts
@@ -28,7 +28,7 @@ import {
   codecOptional,
 } from "@gnu-taler/taler-util";
 import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";
-import { AppLocation } from "../route.js";
+import { AppLocation } from "@gnu-taler/web-util/browser";
 
 export type ChallengeInProgess =
   | DeleteAccountChallenge
diff --git a/packages/bank-ui/src/hooks/regional.ts 
b/packages/bank-ui/src/hooks/regional.ts
index 51f3edad4..274638f74 100644
--- a/packages/bank-ui/src/hooks/regional.ts
+++ b/packages/bank-ui/src/hooks/regional.ts
@@ -33,17 +33,17 @@ import {
 } from "@gnu-taler/taler-util";
 import { useState } from "preact/hooks";
 import _useSWR, { SWRHook, mutate } from "swr";
-import { useBankCoreApiContext } from "../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
 const useSWR = _useSWR as unknown as SWRHook;
 
 export type TransferCalculation =
   | {
-      debit: AmountJson;
-      credit: AmountJson;
-      beforeFee: AmountJson;
-    }
+    debit: AmountJson;
+    credit: AmountJson;
+    beforeFee: AmountJson;
+  }
   | "amount-is-too-small";
 type EstimatorFunction = (
   amount: AmountJson,
@@ -62,7 +62,7 @@ export function revalidateConversionInfo() {
   );
 }
 export function useConversionInfo() {
-  const { conversion, config } = useBankCoreApiContext();
+  const { lib: { conversion }, config } = useBankCoreApiContext();
 
   async function fetcher() {
     return await conversion.getConfig();
@@ -88,7 +88,7 @@ export function useConversionInfo() {
 }
 
 export function useCashinEstimator(): ConversionEstimators {
-  const { conversion } = useBankCoreApiContext();
+  const { lib: { conversion } } = useBankCoreApiContext();
   return {
     estimateByCredit: async (fiatAmount, fee) => {
       const resp = await conversion.getCashinRate({
@@ -144,7 +144,7 @@ export function useCashinEstimator(): ConversionEstimators {
 }
 
 export function useCashoutEstimator(): ConversionEstimators {
-  const { conversion } = useBankCoreApiContext();
+  const { lib: { conversion } } = useBankCoreApiContext();
   return {
     estimateByCredit: async (fiatAmount, fee) => {
       const resp = await conversion.getCashoutRate({
@@ -217,7 +217,7 @@ export function useBusinessAccounts() {
   const { state: credentials } = useSessionState();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
 
   const [offset, setOffset] = useState<number | undefined>();
 
@@ -290,7 +290,7 @@ export function revalidateOnePendingCashouts() {
 }
 export function useOnePendingCashouts(account: string) {
   const { state: credentials } = useSessionState();
-  const { bank: api, config } = useBankCoreApiContext();
+  const { lib: { bank: api }, config } = useBankCoreApiContext();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
 
@@ -350,7 +350,7 @@ export function revalidateCashouts() {
 }
 export function useCashouts(account: string) {
   const { state: credentials } = useSessionState();
-  const { bank: api, config } = useBankCoreApiContext();
+  const { lib: { bank: api }, config } = useBankCoreApiContext();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
 
@@ -406,7 +406,7 @@ export function revalidateCashoutDetails() {
 export function useCashoutDetails(cashoutId: number | undefined) {
   const { state: credentials } = useSessionState();
   const creds = credentials.status !== "loggedIn" ? undefined : credentials;
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
 
   async function fetcher([username, token, id]: [string, AccessToken, number]) 
{
     return api.getCashoutById({ username, token }, id);
@@ -459,7 +459,7 @@ export function useLastMonitorInfo(
   previousMoment: number,
   timeframe: TalerCorebankApi.MonitorTimeframeParam,
 ) {
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
   const { state: credentials } = useSessionState();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
diff --git a/packages/bank-ui/src/hooks/session.ts 
b/packages/bank-ui/src/hooks/session.ts
index 35f87e1be..661d64415 100644
--- a/packages/bank-ui/src/hooks/session.ts
+++ b/packages/bank-ui/src/hooks/session.ts
@@ -86,7 +86,7 @@ export interface SessionStateHandler {
   logIn(info: { username: string; token: AccessToken }): void;
 }
 
-const SESSION_STATE_KEY = buildStorageKey("bank-state", 
codecForSessionState());
+const SESSION_STATE_KEY = buildStorageKey("bank-session", 
codecForSessionState());
 
 /**
  * Return getters and setters for
diff --git a/packages/bank-ui/src/pages/AccountPage/index.ts 
b/packages/bank-ui/src/pages/AccountPage/index.ts
index 757346c5c..8a9471ef4 100644
--- a/packages/bank-ui/src/pages/AccountPage/index.ts
+++ b/packages/bank-ui/src/pages/AccountPage/index.ts
@@ -25,7 +25,7 @@ import { ErrorLoadingWithDebug } from 
"../../components/ErrorLoadingWithDebug.js
 import { LoginForm } from "../LoginForm.js";
 import { useComponentState } from "./state.js";
 import { InvalidIbanView, ReadyView } from "./views.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 
 export interface Props {
   account: string;
diff --git a/packages/bank-ui/src/pages/AccountPage/views.tsx 
b/packages/bank-ui/src/pages/AccountPage/views.tsx
index 3a182ed1b..42892f536 100644
--- a/packages/bank-ui/src/pages/AccountPage/views.tsx
+++ b/packages/bank-ui/src/pages/AccountPage/views.tsx
@@ -22,7 +22,7 @@ import { useBankState } from "../../hooks/bank-state.js";
 import { usePreferences } from "../../hooks/preferences.js";
 import { PaymentOptions } from "../PaymentOptions.js";
 import { State } from "./index.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 
 export function InvalidIbanView({ error }: State.InvalidIban) {
   return (
diff --git a/packages/bank-ui/src/pages/BankFrame.tsx 
b/packages/bank-ui/src/pages/BankFrame.tsx
index 39f042455..6eb7d1b7e 100644
--- a/packages/bank-ui/src/pages/BankFrame.tsx
+++ b/packages/bank-ui/src/pages/BankFrame.tsx
@@ -33,7 +33,7 @@ import {
 } from "@gnu-taler/web-util/browser";
 import { ComponentChildren, Fragment, VNode, h } from "preact";
 import { useEffect, useErrorBoundary, useState } from "preact/hooks";
-import { useBankCoreApiContext } from "../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useSettingsContext } from "../context/settings.js";
 import { useAccountDetails } from "../hooks/account.js";
 import { useBankState } from "../hooks/bank-state.js";
@@ -43,7 +43,7 @@ import {
   usePreferences,
 } from "../hooks/preferences.js";
 import { useSessionState } from "../hooks/session.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { RenderAmount } from "./PaytoWireTransferForm.js";
 import { privatePages } from "../Routing.js";
 
@@ -102,9 +102,9 @@ export function BankFrame({
             session.state.status !== "loggedIn"
               ? undefined
               : () => {
-                  session.logOut();
-                  resetBankState();
-                }
+                session.logOut();
+                resetBankState();
+              }
           }
           sites={
             !settings.topNavSites ? [] : Object.entries(settings.topNavSites)
@@ -234,7 +234,7 @@ function AppActivity(): VNode {
   }>();
   const [status, setStatus] = useState<"ok" | "fail">();
   const d = useBankCoreApiContext();
-  const onBackendActivity = !d ? undefined : d.onBackendActivity;
+  const onBackendActivity = !d ? undefined : d.onActivity;
   const cancelRequest = !d ? undefined : d.cancelRequest;
   const [pref] = usePreferences();
   useEffect(() => {
diff --git a/packages/bank-ui/src/pages/LoginForm.tsx 
b/packages/bank-ui/src/pages/LoginForm.tsx
index 337cfc8b1..904cd39d2 100644
--- a/packages/bank-ui/src/pages/LoginForm.tsx
+++ b/packages/bank-ui/src/pages/LoginForm.tsx
@@ -24,9 +24,9 @@ import {
 } from "@gnu-taler/web-util/browser";
 import { VNode, h } from "preact";
 import { useEffect, useRef, useState } from "preact/hooks";
-import { useBankCoreApiContext } from "../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useSessionState } from "../hooks/session.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { undefinedIfEmpty } from "../utils.js";
 import { doAutoFocus } from "./PaytoWireTransferForm.js";
 import { USERNAME_REGEX } from "./RegistrationPage.js";
@@ -52,7 +52,7 @@ export function LoginForm({
   );
   const [password, setPassword] = useState<string | undefined>();
   const { i18n } = useTranslationContext();
-  const { authenticator } = useBankCoreApiContext();
+  const { lib: { auth: authenticator } } = useBankCoreApiContext();
   const [notification, withErrorHandler] = useLocalNotificationHandler();
   const { config } = useBankCoreApiContext();
 
@@ -78,25 +78,25 @@ export function LoginForm({
     !username || !password
       ? undefined
       : withErrorHandler(
-          async () =>
-            authenticator(username).createAccessToken(password, {
-              // scope: "readwrite" as "write", // FIX: different than merchant
-              scope: "readwrite",
-              duration: { d_us: "forever" },
-              refreshable: true,
-            }),
-          (result) => {
-            session.logIn({ username, token: result.body.access_token });
-          },
-          (fail) => {
-            switch (fail.case) {
-              case HttpStatusCode.Unauthorized:
-                return i18n.str`Wrong credentials for "${username}"`;
-              case HttpStatusCode.NotFound:
-                return i18n.str`Account not found`;
-            }
-          },
-        );
+        async () =>
+          authenticator(username).createAccessToken(password, {
+            // scope: "readwrite" as "write", // FIX: different than merchant
+            scope: "readwrite",
+            duration: { d_us: "forever" },
+            refreshable: true,
+          }),
+        (result) => {
+          session.logIn({ username, token: result.body.access_token });
+        },
+        (fail) => {
+          switch (fail.case) {
+            case HttpStatusCode.Unauthorized:
+              return i18n.str`Wrong credentials for "${username}"`;
+            case HttpStatusCode.NotFound:
+              return i18n.str`Account not found`;
+          }
+        },
+      );
 
   return (
     <div class="flex min-h-full flex-col justify-center ">
diff --git a/packages/bank-ui/src/pages/OperationState/index.ts 
b/packages/bank-ui/src/pages/OperationState/index.ts
index 8ab5659b1..4a7888ee3 100644
--- a/packages/bank-ui/src/pages/OperationState/index.ts
+++ b/packages/bank-ui/src/pages/OperationState/index.ts
@@ -34,7 +34,7 @@ import {
   NeedConfirmationView,
   ReadyView,
 } from "./views.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 
 export interface Props {
   currency: string;
@@ -106,15 +106,15 @@ export namespace State {
     account: string;
     routeHere: RouteDefinition<{ wopid: string }>;
     onAbort:
-      | undefined
-      | (() => Promise<
-          TalerCoreBankErrorsByMethod<"abortWithdrawalById"> | undefined
-        >);
+    | undefined
+    | (() => Promise<
+      TalerCoreBankErrorsByMethod<"abortWithdrawalById"> | undefined
+    >);
     onConfirm:
-      | undefined
-      | (() => Promise<
-          TalerCoreBankErrorsByMethod<"confirmWithdrawalById"> | undefined
-        >);
+    | undefined
+    | (() => Promise<
+      TalerCoreBankErrorsByMethod<"confirmWithdrawalById"> | undefined
+    >);
     error: undefined;
     id: string;
   }
diff --git a/packages/bank-ui/src/pages/OperationState/state.ts 
b/packages/bank-ui/src/pages/OperationState/state.ts
index 80af1a91d..a0cbc66b9 100644
--- a/packages/bank-ui/src/pages/OperationState/state.ts
+++ b/packages/bank-ui/src/pages/OperationState/state.ts
@@ -27,7 +27,7 @@ import {
 import { utils } from "@gnu-taler/web-util/browser";
 import { useEffect, useState } from "preact/hooks";
 import { mutate } from "swr";
-import { useBankCoreApiContext } from "../../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useWithdrawalDetails } from "../../hooks/account.js";
 import { useSessionState } from "../../hooks/session.js";
 import { useBankState } from "../../hooks/bank-state.js";
@@ -45,7 +45,7 @@ export function useComponentState({
   const [bankState, updateBankState] = useBankState();
   const { state: credentials } = useSessionState();
   const creds = credentials.status !== "loggedIn" ? undefined : credentials;
-  const { bank } = useBankCoreApiContext();
+  const { lib: { bank } } = useBankCoreApiContext();
 
   const [failure, setFailure] = useState<
     TalerCoreBankErrorsByMethod<"createWithdrawal"> | undefined
@@ -191,9 +191,9 @@ export function useComponentState({
         routeClose,
         onAbort: !creds
           ? async () => {
-              onAbort();
-              return undefined;
-            }
+            onAbort();
+            return undefined;
+          }
           : doAbort,
       };
     }
diff --git a/packages/bank-ui/src/pages/OperationState/views.tsx 
b/packages/bank-ui/src/pages/OperationState/views.tsx
index 330fe1072..62308eca6 100644
--- a/packages/bank-ui/src/pages/OperationState/views.tsx
+++ b/packages/bank-ui/src/pages/OperationState/views.tsx
@@ -27,6 +27,7 @@ import {
   LocalNotificationBanner,
   notifyInfo,
   useLocalNotification,
+  useTalerWalletIntegrationAPI,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
@@ -36,7 +37,6 @@ import { useBankState } from "../../hooks/bank-state.js";
 import { usePreferences } from "../../hooks/preferences.js";
 import { ShouldBeSameUser } from "../WithdrawalConfirmationQuestion.js";
 import { State } from "./index.js";
-import { useTalerWalletIntegrationAPI } from 
"../../context/wallet-integration.js";
 
 export function InvalidPaytoView({ payto }: State.InvalidPayto) {
   return <div>Payto from server is not valid &quot;{payto}&quot;</div>;
diff --git a/packages/bank-ui/src/pages/PaymentOptions.tsx 
b/packages/bank-ui/src/pages/PaymentOptions.tsx
index 189a7665e..386fe31bc 100644
--- a/packages/bank-ui/src/pages/PaymentOptions.tsx
+++ b/packages/bank-ui/src/pages/PaymentOptions.tsx
@@ -21,7 +21,7 @@ import { useEffect } from "preact/hooks";
 import { useWithdrawalDetails } from "../hooks/account.js";
 import { useBankState } from "../hooks/bank-state.js";
 import { useSessionState } from "../hooks/session.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { PaytoWireTransferForm } from "./PaytoWireTransferForm.js";
 import { WalletWithdrawForm } from "./WalletWithdrawForm.js";
 
diff --git a/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx 
b/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx
index 7812a1da0..22db739b1 100644
--- a/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx
+++ b/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx
@@ -42,10 +42,10 @@ import {
 import { ComponentChildren, Fragment, Ref, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { mutate } from "swr";
-import { useBankCoreApiContext } from "../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useBankState } from "../hooks/bank-state.js";
 import { useSessionState } from "../hooks/session.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { undefinedIfEmpty, validateIBAN, validateTalerBank } from 
"../utils.js";
 
 interface Props {
@@ -82,7 +82,7 @@ export function PaytoWireTransferForm({
   const isRawPayto = inputType !== "form";
 
   const { state: credentials } = useSessionState();
-  const { bank: api, config, url } = useBankCoreApiContext();
+  const { lib: { bank: api }, config, url } = useBankCoreApiContext();
 
   const sendingToFixedAccount = withAccount !== undefined;
 
diff --git a/packages/bank-ui/src/pages/ProfileNavigation.tsx 
b/packages/bank-ui/src/pages/ProfileNavigation.tsx
index 1775d9329..1cf357ceb 100644
--- a/packages/bank-ui/src/pages/ProfileNavigation.tsx
+++ b/packages/bank-ui/src/pages/ProfileNavigation.tsx
@@ -14,12 +14,11 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 import { assertUnreachable } from "@gnu-taler/taler-util";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import { useNavigationContext, useTranslationContext } from 
"@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
-import { useBankCoreApiContext } from "../context/config.js";
-import { useNavigationContext } from "../context/navigation.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useSessionState } from "../hooks/session.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 
 export function ProfileNavigation({
   current,
diff --git a/packages/bank-ui/src/pages/QrCodeSection.tsx 
b/packages/bank-ui/src/pages/QrCodeSection.tsx
index f442857a8..156c18f48 100644
--- a/packages/bank-ui/src/pages/QrCodeSection.tsx
+++ b/packages/bank-ui/src/pages/QrCodeSection.tsx
@@ -23,13 +23,13 @@ import {
   Button,
   LocalNotificationBanner,
   useLocalNotificationHandler,
+  useTalerWalletIntegrationAPI,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { useEffect } from "preact/hooks";
 import { QR } from "../components/QR.js";
-import { useBankCoreApiContext } from "../context/config.js";
-import { useTalerWalletIntegrationAPI } from 
"../context/wallet-integration.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useSessionState } from "../hooks/session.js";
 
 export function QrCodeSection({
@@ -51,7 +51,7 @@ export function QrCodeSection({
 
   const [notification, handleError] = useLocalNotificationHandler();
 
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
 
   const onAbortHandler = handleError(
     async () => {
diff --git a/packages/bank-ui/src/pages/RegistrationPage.tsx 
b/packages/bank-ui/src/pages/RegistrationPage.tsx
index 2ce9d96cc..d7093d973 100644
--- a/packages/bank-ui/src/pages/RegistrationPage.tsx
+++ b/packages/bank-ui/src/pages/RegistrationPage.tsx
@@ -26,9 +26,9 @@ import {
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
-import { useBankCoreApiContext } from "../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useSettingsContext } from "../context/settings.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { undefinedIfEmpty } from "../utils.js";
 import { getRandomPassword, getRandomUsername } from "./rnd.js";
 
@@ -78,7 +78,7 @@ function RegistrationForm({
   const [notification, , handleError] = useLocalNotification();
   const settings = useSettingsContext();
 
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
   // const { register } = useTestingAPI();
   const { i18n } = useTranslationContext();
 
diff --git a/packages/bank-ui/src/pages/SolveChallengePage.tsx 
b/packages/bank-ui/src/pages/SolveChallengePage.tsx
index 30ca122bf..48d62f1de 100644
--- a/packages/bank-ui/src/pages/SolveChallengePage.tsx
+++ b/packages/bank-ui/src/pages/SolveChallengePage.tsx
@@ -32,19 +32,19 @@ import {
   LocalNotificationBanner,
   ShowInputErrorLabel,
   useLocalNotification,
+  useNavigationContext,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import { ErrorLoadingWithDebug } from "../components/ErrorLoadingWithDebug.js";
 import { Time } from "../components/Time.js";
-import { useBankCoreApiContext } from "../context/config.js";
-import { useNavigationContext } from "../context/navigation.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useWithdrawalDetails } from "../hooks/account.js";
 import { ChallengeInProgess, useBankState } from "../hooks/bank-state.js";
 import { useConversionInfo } from "../hooks/regional.js";
 import { useSessionState } from "../hooks/session.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { undefinedIfEmpty } from "../utils.js";
 import { RenderAmount } from "./PaytoWireTransferForm.js";
 import { OperationNotFound } from "./WithdrawalQRCode.js";
@@ -58,7 +58,7 @@ export function SolveChallengePage({
   onChallengeCompleted: () => void;
   routeClose: RouteDefinition;
 }): VNode {
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
   const { i18n } = useTranslationContext();
   const [bankState, updateBankState] = useBankState();
   const [code, setCode] = useState<string | undefined>(undefined);
diff --git a/packages/bank-ui/src/pages/WalletWithdrawForm.tsx 
b/packages/bank-ui/src/pages/WalletWithdrawForm.tsx
index 2aa0338ad..b95b109d5 100644
--- a/packages/bank-ui/src/pages/WalletWithdrawForm.tsx
+++ b/packages/bank-ui/src/pages/WalletWithdrawForm.tsx
@@ -33,11 +33,11 @@ import {
 import { VNode, h } from "preact";
 import { forwardRef } from "preact/compat";
 import { useState } from "preact/hooks";
-import { useBankCoreApiContext } from "../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useSessionState } from "../hooks/session.js";
 import { useBankState } from "../hooks/bank-state.js";
 import { usePreferences } from "../hooks/preferences.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { undefinedIfEmpty } from "../utils.js";
 import { OperationState } from "./OperationState/index.js";
 import {
@@ -70,7 +70,7 @@ function OldWithdrawalForm({
   // const { navigateTo } = useNavigationContext();
 
   const [bankState, updateBankState] = useBankState();
-  const { bank: api, config } = useBankCoreApiContext();
+  const { lib: { bank: api }, config } = useBankCoreApiContext();
 
   const { state: credentials } = useSessionState();
   const creds = credentials.status !== "loggedIn" ? undefined : credentials;
@@ -105,12 +105,12 @@ function OldWithdrawalForm({
           class="font-semibold text-yellow-700 hover:text-yellow-600"
           name="complete operation"
           href={url}
-          // onClick={(e) => {
-          //   e.preventDefault()
-          //   walletInegrationApi.publishTalerAction(uri, () => {
-          //     navigateTo(url)
-          //   })
-          // }}
+        // onClick={(e) => {
+        //   e.preventDefault()
+        //   walletInegrationApi.publishTalerAction(uri, () => {
+        //     navigateTo(url)
+        //   })
+        // }}
         >
           <i18n.Translate>this page</i18n.Translate>
         </a>
@@ -392,7 +392,7 @@ export function WalletWithdrawForm({
             routeClose={routeCancel}
             routeHere={routeOperationDetails}
             onAbort={onOperationAborted}
-            // route={routeCancel}
+          // route={routeCancel}
           />
         )}
       </div>
diff --git a/packages/bank-ui/src/pages/WireTransfer.tsx 
b/packages/bank-ui/src/pages/WireTransfer.tsx
index 59d6b2b0f..f45390938 100644
--- a/packages/bank-ui/src/pages/WireTransfer.tsx
+++ b/packages/bank-ui/src/pages/WireTransfer.tsx
@@ -30,7 +30,7 @@ import { useAccountDetails } from "../hooks/account.js";
 import { useSessionState } from "../hooks/session.js";
 import { LoginForm } from "./LoginForm.js";
 import { PaytoWireTransferForm } from "./PaytoWireTransferForm.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 
 export function WireTransfer({
   toAccount,
diff --git a/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx 
b/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
index c7bdaaf21..1eec8bfc2 100644
--- a/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
+++ b/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
@@ -35,11 +35,11 @@ import {
 } from "@gnu-taler/web-util/browser";
 import { ComponentChildren, Fragment, VNode, h } from "preact";
 import { mutate } from "swr";
-import { useBankCoreApiContext } from "../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useBankState } from "../hooks/bank-state.js";
 import { usePreferences } from "../hooks/preferences.js";
 import { useSessionState } from "../hooks/session.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { LoginForm } from "./LoginForm.js";
 import { RenderAmount } from "./PaytoWireTransferForm.js";
 
@@ -74,7 +74,7 @@ export function WithdrawalConfirmationQuestion({
 
   const [notification, notify, handleError] = useLocalNotification();
 
-  const { config, bank: api } = useBankCoreApiContext();
+  const { config, lib: { bank: api } } = useBankCoreApiContext();
 
   async function doTransfer() {
     await handleError(async () => {
diff --git a/packages/bank-ui/src/pages/WithdrawalOperationPage.tsx 
b/packages/bank-ui/src/pages/WithdrawalOperationPage.tsx
index fb280cf9c..9dee1403a 100644
--- a/packages/bank-ui/src/pages/WithdrawalOperationPage.tsx
+++ b/packages/bank-ui/src/pages/WithdrawalOperationPage.tsx
@@ -17,9 +17,9 @@
 import { parseWithdrawUri, stringifyWithdrawUri } from "@gnu-taler/taler-util";
 import { Attention, useTranslationContext } from "@gnu-taler/web-util/browser";
 import { VNode, h } from "preact";
-import { useBankCoreApiContext } from "../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useBankState } from "../hooks/bank-state.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { WithdrawalQRCode } from "./WithdrawalQRCode.js";
 
 export function WithdrawalOperationPage({
@@ -36,7 +36,7 @@ export function WithdrawalOperationPage({
   routeClose: RouteDefinition;
   routeWithdrawalDetails: RouteDefinition<{ wopid: string }>;
 }): VNode {
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
   const uri = stringifyWithdrawUri({
     bankIntegrationApiBaseUrl: api.getIntegrationAPI().href,
     withdrawalOperationId: operationId,
diff --git a/packages/bank-ui/src/pages/WithdrawalQRCode.tsx 
b/packages/bank-ui/src/pages/WithdrawalQRCode.tsx
index 9765147d1..b61f0cc8f 100644
--- a/packages/bank-ui/src/pages/WithdrawalQRCode.tsx
+++ b/packages/bank-ui/src/pages/WithdrawalQRCode.tsx
@@ -31,7 +31,7 @@ import {
 import { VNode, h } from "preact";
 import { ErrorLoadingWithDebug } from "../components/ErrorLoadingWithDebug.js";
 import { useWithdrawalDetails } from "../hooks/account.js";
-import { RouteDefinition } from "../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { QrCodeSection } from "./QrCodeSection.js";
 import { WithdrawalConfirmationQuestion } from 
"./WithdrawalConfirmationQuestion.js";
 
diff --git a/packages/bank-ui/src/pages/account/CashoutListForAccount.tsx 
b/packages/bank-ui/src/pages/account/CashoutListForAccount.tsx
index bd9352b21..301978eaa 100644
--- a/packages/bank-ui/src/pages/account/CashoutListForAccount.tsx
+++ b/packages/bank-ui/src/pages/account/CashoutListForAccount.tsx
@@ -19,7 +19,7 @@ import { Cashouts } from "../../components/Cashouts/index.js";
 import { useSessionState } from "../../hooks/session.js";
 import { ProfileNavigation } from "../ProfileNavigation.js";
 import { CreateCashout } from "../regional/CreateCashout.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 
 interface Props {
   account: string;
diff --git a/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx 
b/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx
index 13685c2c8..bd3961bb7 100644
--- a/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx
+++ b/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx
@@ -35,11 +35,11 @@ import {
 import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { ErrorLoadingWithDebug } from 
"../../components/ErrorLoadingWithDebug.js";
-import { useBankCoreApiContext } from "../../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useAccountDetails } from "../../hooks/account.js";
 import { useSessionState } from "../../hooks/session.js";
 import { useBankState } from "../../hooks/bank-state.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { LoginForm } from "../LoginForm.js";
 import { ProfileNavigation } from "../ProfileNavigation.js";
 import { AccountForm } from "../admin/AccountForm.js";
@@ -70,7 +70,7 @@ export function ShowAccountDetails({
   const { i18n } = useTranslationContext();
   const { state: credentials } = useSessionState();
   const creds = credentials.status !== "loggedIn" ? undefined : credentials;
-  const { bank } = useBankCoreApiContext();
+  const { lib: { bank } } = useBankCoreApiContext();
   const accountIsTheCurrentUser =
     credentials.status === "loggedIn"
       ? credentials.username === account
diff --git a/packages/bank-ui/src/pages/account/UpdateAccountPassword.tsx 
b/packages/bank-ui/src/pages/account/UpdateAccountPassword.tsx
index 1147e723a..58010ecb3 100644
--- a/packages/bank-ui/src/pages/account/UpdateAccountPassword.tsx
+++ b/packages/bank-ui/src/pages/account/UpdateAccountPassword.tsx
@@ -29,10 +29,10 @@ import {
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
-import { useBankCoreApiContext } from "../../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useSessionState } from "../../hooks/session.js";
 import { useBankState } from "../../hooks/bank-state.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { undefinedIfEmpty } from "../../utils.js";
 import { doAutoFocus } from "../PaytoWireTransferForm.js";
 import { ProfileNavigation } from "../ProfileNavigation.js";
@@ -66,7 +66,7 @@ export function UpdateAccountPassword({
   const { state: credentials } = useSessionState();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
 
   const [current, setCurrent] = useState<string | undefined>();
   const [password, setPassword] = useState<string | undefined>();
diff --git a/packages/bank-ui/src/pages/admin/AccountForm.tsx 
b/packages/bank-ui/src/pages/admin/AccountForm.tsx
index 10b6afdf9..026f6e9b3 100644
--- a/packages/bank-ui/src/pages/admin/AccountForm.tsx
+++ b/packages/bank-ui/src/pages/admin/AccountForm.tsx
@@ -30,7 +30,7 @@ import {
 } from "@gnu-taler/web-util/browser";
 import { ComponentChildren, VNode, h } from "preact";
 import { useState } from "preact/hooks";
-import { VersionHint, useBankCoreApiContext } from "../../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useSessionState } from "../../hooks/session.js";
 import {
   ErrorMessageMappingFor,
@@ -92,7 +92,7 @@ export function AccountForm<PurposeType extends keyof 
ChangeByPurposeType>({
   onChange: ChangeByPurposeType[PurposeType];
   purpose: PurposeType;
 }): VNode {
-  const { config, hints, url } = useBankCoreApiContext();
+  const { config, url } = useBankCoreApiContext();
   const { i18n } = useTranslationContext();
   const { state: credentials } = useSessionState();
   const [form, setForm] = useState<AccountFormData>({});
@@ -125,8 +125,6 @@ export function AccountForm<PurposeType extends keyof 
ChangeByPurposeType>({
     tan_channel: template?.tan_channel,
   };
 
-  const OLD_CASHOUT_API = hints.indexOf(VersionHint.CASHOUT_BEFORE_2FA) !== -1;
-
   const userIsAdmin =
     credentials.status !== "loggedIn" ? false : 
credentials.isUserAdministrator;
 
@@ -144,9 +142,6 @@ export function AccountForm<PurposeType extends keyof 
ChangeByPurposeType>({
     userIsAdmin && (purpose === "create" || purpose === "update");
   const editableAccount = purpose === "create" && userIsAdmin;
 
-  const hasPhone = !!defaultValue.phone || !!form.phone;
-  const hasEmail = !!defaultValue.email || !!form.email;
-
   function updateForm(newForm: typeof defaultValue): void {
     const trimmedAmountStr = newForm.debit_threshold?.trim();
     const parsedAmount = Amounts.parse(
@@ -503,138 +498,6 @@ export function AccountForm<PurposeType extends keyof 
ChangeByPurposeType>({
             />
           )}
 
-          {/* channel, not shown if old cashout api */}
-          {OLD_CASHOUT_API ||
-          config.supported_tan_channels.length === 0 ? undefined : (
-            <div class="sm:col-span-5">
-              <label
-                class="block text-sm font-medium leading-6 text-gray-900"
-                for="channel"
-              >
-                {i18n.str`Enable second factor authentication`}
-              </label>
-              <div class="mt-2 max-w-xl text-sm text-gray-500">
-                <div class="px-4 mt-4 grid grid-cols-1 gap-y-6">
-                  {config.supported_tan_channels.indexOf(TanChannel.EMAIL) ===
-                  -1 ? undefined : (
-                    <label
-                      onClick={(e) => {
-                        if (!hasEmail) return;
-                        if (form.tan_channel === TanChannel.EMAIL) {
-                          form.tan_channel = "remove";
-                        } else {
-                          form.tan_channel = TanChannel.EMAIL;
-                        }
-                        updateForm(structuredClone(form));
-                        e.preventDefault();
-                      }}
-                      data-disabled={purpose === "show" || !hasEmail}
-                      data-selected={
-                        (form.tan_channel ?? defaultValue.tan_channel) ===
-                        TanChannel.EMAIL
-                      }
-                      class="relative flex 
data-[disabled=false]:cursor-pointer rounded-lg border bg-white 
data-[disabled=true]:bg-gray-200 p-4 shadow-sm focus:outline-none 
border-gray-300 data-[selected=true]:ring-2 
data-[selected=true]:ring-indigo-600"
-                    >
-                      <input
-                        type="radio"
-                        name="channel"
-                        value="Newsletter"
-                        class="sr-only"
-                      />
-                      <span class="flex flex-1">
-                        <span class="flex flex-col">
-                          <span
-                            id="project-type-0-label"
-                            class="block text-sm font-medium text-gray-900 "
-                          >
-                            <i18n.Translate>Using email</i18n.Translate>
-                          </span>
-                          {purpose !== "show" &&
-                            !hasEmail &&
-                            i18n.str`Add an email in your profile to enable 
this option`}
-                        </span>
-                      </span>
-                      <svg
-                        data-selected={
-                          (form.tan_channel ?? defaultValue.tan_channel) ===
-                          TanChannel.EMAIL
-                        }
-                        class="h-5 w-5 text-indigo-600 
data-[selected=false]:hidden"
-                        viewBox="0 0 20 20"
-                        fill="currentColor"
-                        aria-hidden="true"
-                      >
-                        <path
-                          fill-rule="evenodd"
-                          d="M10 18a8 8 0 100-16 8 8 0 000 
16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 
1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
-                          clip-rule="evenodd"
-                        />
-                      </svg>
-                    </label>
-                  )}
-
-                  {config.supported_tan_channels.indexOf(TanChannel.SMS) ===
-                  -1 ? undefined : (
-                    <label
-                      onClick={(e) => {
-                        if (!hasPhone) return;
-                        if (form.tan_channel === TanChannel.SMS) {
-                          form.tan_channel = "remove";
-                        } else {
-                          form.tan_channel = TanChannel.SMS;
-                        }
-                        updateForm(structuredClone(form));
-                        e.preventDefault();
-                      }}
-                      data-disabled={purpose === "show" || !hasPhone}
-                      data-selected={
-                        (form.tan_channel ?? defaultValue.tan_channel) ===
-                        TanChannel.SMS
-                      }
-                      class="relative flex 
data-[disabled=false]:cursor-pointer rounded-lg border 
data-[disabled=true]:bg-gray-200 p-4 shadow-sm focus:outline-none 
border-gray-300 data-[selected=true]:ring-2 
data-[selected=true]:ring-indigo-600"
-                    >
-                      <input
-                        type="radio"
-                        name="channel"
-                        value="Existing Customers"
-                        class="sr-only"
-                      />
-                      <span class="flex flex-1">
-                        <span class="flex flex-col">
-                          <span
-                            id="project-type-1-label"
-                            class="block text-sm font-medium text-gray-900"
-                          >
-                            <i18n.Translate>Using SMS</i18n.Translate>
-                          </span>
-                          {purpose !== "show" &&
-                            !hasPhone &&
-                            i18n.str`Add a phone number in your profile to 
enable this option`}
-                        </span>
-                      </span>
-                      <svg
-                        data-selected={
-                          (form.tan_channel ?? defaultValue.tan_channel) ===
-                          TanChannel.SMS
-                        }
-                        class="h-5 w-5 text-indigo-600 
data-[selected=false]:hidden"
-                        viewBox="0 0 20 20"
-                        fill="currentColor"
-                        aria-hidden="true"
-                      >
-                        <path
-                          fill-rule="evenodd"
-                          d="M10 18a8 8 0 100-16 8 8 0 000 
16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 
1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
-                          clip-rule="evenodd"
-                        />
-                      </svg>
-                    </label>
-                  )}
-                </div>
-              </div>
-            </div>
-          )}
-
           <div class="sm:col-span-5">
             <label
               for="debit"
@@ -649,9 +512,9 @@ export function AccountForm<PurposeType extends keyof 
ChangeByPurposeType>({
                 !editableThreshold
                   ? undefined
                   : (e) => {
-                      form.debit_threshold = e as AmountString;
-                      updateForm(structuredClone(form));
-                    }
+                    form.debit_threshold = e as AmountString;
+                    updateForm(structuredClone(form));
+                  }
               }
             />
             <ShowInputErrorLabel
diff --git a/packages/bank-ui/src/pages/admin/AccountList.tsx 
b/packages/bank-ui/src/pages/admin/AccountList.tsx
index 75bc014eb..c4e529f9f 100644
--- a/packages/bank-ui/src/pages/admin/AccountList.tsx
+++ b/packages/bank-ui/src/pages/admin/AccountList.tsx
@@ -22,9 +22,9 @@ import {
 import { Loading, useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
 import { ErrorLoadingWithDebug } from 
"../../components/ErrorLoadingWithDebug.js";
-import { useBankCoreApiContext } from "../../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useBusinessAccounts } from "../../hooks/regional.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { RenderAmount } from "../PaytoWireTransferForm.js";
 
 interface Props {
diff --git a/packages/bank-ui/src/pages/admin/AdminHome.tsx 
b/packages/bank-ui/src/pages/admin/AdminHome.tsx
index 613f5c1ef..94b88dc89 100644
--- a/packages/bank-ui/src/pages/admin/AdminHome.tsx
+++ b/packages/bank-ui/src/pages/admin/AdminHome.tsx
@@ -39,9 +39,9 @@ import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { ErrorLoadingWithDebug } from 
"../../components/ErrorLoadingWithDebug.js";
 import { Transactions } from "../../components/Transactions/index.js";
-import { useBankCoreApiContext } from "../../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useConversionInfo, useLastMonitorInfo } from 
"../../hooks/regional.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { RenderAmount } from "../PaytoWireTransferForm.js";
 import { WireTransfer } from "../WireTransfer.js";
 import { AccountList } from "./AccountList.js";
@@ -363,7 +363,7 @@ function Metrics({
       </div>
       <dl class="mt-5 grid grid-cols-1 md:grid-cols-2  divide-y 
divide-gray-200 overflow-hidden rounded-lg bg-white shadow-lg md:divide-x 
md:divide-y-0">
         {resp.current.body.type !== "with-conversions" ||
-        resp.previous.body.type !== "with-conversions" ? undefined : (
+          resp.previous.body.type !== "with-conversions" ? undefined : (
           <Fragment>
             <div class="px-4 py-5 sm:p-6">
               <dt class="text-base font-normal text-gray-900">
@@ -462,9 +462,9 @@ function MetricValue({
 
   const rate =
     !currAmount ||
-    Number.isNaN(currAmount) ||
-    !prevAmount ||
-    Number.isNaN(prevAmount)
+      Number.isNaN(currAmount) ||
+      !prevAmount ||
+      Number.isNaN(prevAmount)
       ? 0
       : cmp === -1
         ? 1 - Math.round(currAmount) / Math.round(prevAmount)
diff --git a/packages/bank-ui/src/pages/admin/CreateNewAccount.tsx 
b/packages/bank-ui/src/pages/admin/CreateNewAccount.tsx
index b14f5b7ca..ecbb18b57 100644
--- a/packages/bank-ui/src/pages/admin/CreateNewAccount.tsx
+++ b/packages/bank-ui/src/pages/admin/CreateNewAccount.tsx
@@ -30,9 +30,9 @@ import {
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
-import { useBankCoreApiContext } from "../../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useSessionState } from "../../hooks/session.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { AccountForm } from "./AccountForm.js";
 
 export function CreateNewAccount({
@@ -46,7 +46,7 @@ export function CreateNewAccount({
   const { state: credentials } = useSessionState();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
 
   const [submitAccount, setSubmitAccount] = useState<
     TalerCorebankApi.RegisterAccountRequest | undefined
diff --git a/packages/bank-ui/src/pages/admin/DownloadStats.tsx 
b/packages/bank-ui/src/pages/admin/DownloadStats.tsx
index bef12c580..b9ae401e7 100644
--- a/packages/bank-ui/src/pages/admin/DownloadStats.tsx
+++ b/packages/bank-ui/src/pages/admin/DownloadStats.tsx
@@ -29,9 +29,9 @@ import {
 } from "@gnu-taler/web-util/browser";
 import { VNode, h } from "preact";
 import { useState } from "preact/hooks";
-import { useBankCoreApiContext } from "../../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useSessionState } from "../../hooks/session.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { getTimeframesForDate } from "./AdminHome.js";
 
 interface Props {
@@ -59,7 +59,7 @@ export function DownloadStats({ routeCancel }: Props): VNode {
     credentials.status !== "loggedIn" || !credentials.isUserAdministrator
       ? undefined
       : credentials;
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
 
   const [options, setOptions] = useState<Options>({
     compareWithPrevious: true,
@@ -460,9 +460,9 @@ async function fetchAllStatus(
       // await delay()
       const previous = options.compareWithPrevious
         ? await api.getMonitor(token, {
-            timeframe: frame.timeframe,
-            which: frame.moment.previous,
-          })
+          timeframe: frame.timeframe,
+          which: frame.moment.previous,
+        })
         : undefined;
 
       if (previous && previous.type === "fail" && options.endOnFirstFail) {
diff --git a/packages/bank-ui/src/pages/admin/RemoveAccount.tsx 
b/packages/bank-ui/src/pages/admin/RemoveAccount.tsx
index dad315d98..f9c23ea72 100644
--- a/packages/bank-ui/src/pages/admin/RemoveAccount.tsx
+++ b/packages/bank-ui/src/pages/admin/RemoveAccount.tsx
@@ -34,14 +34,14 @@ import {
 import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { ErrorLoadingWithDebug } from 
"../../components/ErrorLoadingWithDebug.js";
-import { useBankCoreApiContext } from "../../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useAccountDetails } from "../../hooks/account.js";
 import { useSessionState } from "../../hooks/session.js";
 import { undefinedIfEmpty } from "../../utils.js";
 import { LoginForm } from "../LoginForm.js";
 import { doAutoFocus } from "../PaytoWireTransferForm.js";
 import { useBankState } from "../../hooks/bank-state.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 
 export function RemoveAccount({
   account,
@@ -64,7 +64,7 @@ export function RemoveAccount({
 
   const { state } = useSessionState();
   const token = state.status !== "loggedIn" ? undefined : state.token;
-  const { bank: api } = useBankCoreApiContext();
+  const { lib: { bank: api } } = useBankCoreApiContext();
   const [notification, notify, handleError] = useLocalNotification();
   const [, updateBankState] = useBankState();
 
diff --git a/packages/bank-ui/src/pages/regional/ConversionConfig.tsx 
b/packages/bank-ui/src/pages/regional/ConversionConfig.tsx
index 014142e97..7527290d0 100644
--- a/packages/bank-ui/src/pages/regional/ConversionConfig.tsx
+++ b/packages/bank-ui/src/pages/regional/ConversionConfig.tsx
@@ -35,7 +35,7 @@ import {
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
 import { useEffect, useState } from "preact/hooks";
-import { useBankCoreApiContext } from "../../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useSessionState } from "../../hooks/session.js";
 import {
   TransferCalculation,
@@ -43,7 +43,7 @@ import {
   useCashoutEstimator,
   useConversionInfo,
 } from "../../hooks/regional.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { undefinedIfEmpty } from "../../utils.js";
 import { InputAmount, RenderAmount } from "../PaytoWireTransferForm.js";
 import { ProfileNavigation } from "../ProfileNavigation.js";
@@ -104,7 +104,7 @@ function useComponentState({
   return function afterComponentLoads() {
     const { i18n } = useTranslationContext();
 
-    const { conversion } = useBankCoreApiContext();
+    const { lib: { conversion } } = useBankCoreApiContext();
 
     const [notification, notify, handleError] = useLocalNotification();
 
@@ -519,8 +519,8 @@ function useComponentState({
                     </div>
 
                     {cashoutCalc &&
-                    status.status === "ok" &&
-                    Amounts.cmp(status.result.amount, cashoutCalc.credit) <
+                      status.status === "ok" &&
+                      Amounts.cmp(status.result.amount, cashoutCalc.credit) <
                       0 ? (
                       <div class="p-4">
                         <Attention
diff --git a/packages/bank-ui/src/pages/regional/CreateCashout.tsx 
b/packages/bank-ui/src/pages/regional/CreateCashout.tsx
index 20d6b0bff..393240dee 100644
--- a/packages/bank-ui/src/pages/regional/CreateCashout.tsx
+++ b/packages/bank-ui/src/pages/regional/CreateCashout.tsx
@@ -37,7 +37,7 @@ import {
 import { Fragment, VNode, h } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import { ErrorLoadingWithDebug } from 
"../../components/ErrorLoadingWithDebug.js";
-import { VersionHint, useBankCoreApiContext } from "../../context/config.js";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
 import { useAccountDetails } from "../../hooks/account.js";
 import { useBankState } from "../../hooks/bank-state.js";
 import {
@@ -46,7 +46,7 @@ import {
   useConversionInfo,
 } from "../../hooks/regional.js";
 import { useSessionState } from "../../hooks/session.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { TanChannel, undefinedIfEmpty } from "../../utils.js";
 import { LoginForm } from "../LoginForm.js";
 import {
@@ -90,7 +90,7 @@ export function CreateCashout({
   const creds = credentials.status !== "loggedIn" ? undefined : credentials;
   const [, updateBankState] = useBankState();
 
-  const { bank: api, config, hints } = useBankCoreApiContext();
+  const { lib: { bank: api }, config, hints } = useBankCoreApiContext();
   const [form, setForm] = useState<Partial<FormType>>({ isDebit: true });
   const [notification, notify, handleError] = useLocalNotification();
   const info = useConversionInfo();
@@ -116,8 +116,6 @@ export function CreateCashout({
     );
   }
 
-  const OLD_CASHOUT_API = hints.indexOf(VersionHint.CASHOUT_BEFORE_2FA) !== -1;
-
   if (!resultAccount) {
     return <Loading />;
   }
@@ -198,8 +196,7 @@ export function CreateCashout({
    * depending on the isDebit flag
    */
   const inputAmount = Amounts.parseOrThrow(
-    `${form.isDebit ? regional_currency : fiat_currency}:${
-      !form.amount ? "0" : form.amount
+    `${form.isDebit ? regional_currency : fiat_currency}:${!form.amount ? "0" 
: form.amount
     }`,
   );
 
@@ -240,19 +237,17 @@ export function CreateCashout({
         : Amounts.cmp(limit, calc.debit) === -1
           ? i18n.str`Balance is not enough`
           : form.isDebit &&
-              Amounts.cmp(inputAmount, conversionInfo.cashout_min_amount) < 1
-            ? i18n.str`Needs to be higher than ${
-                Amounts.stringifyValueWithSpec(
-                  Amounts.parseOrThrow(conversionInfo.cashout_min_amount),
-                  regional_currency_specification,
-                ).normal
+            Amounts.cmp(inputAmount, conversionInfo.cashout_min_amount) < 1
+            ? i18n.str`Needs to be higher than 
${Amounts.stringifyValueWithSpec(
+              Amounts.parseOrThrow(conversionInfo.cashout_min_amount),
+              regional_currency_specification,
+            ).normal
               }`
             : calculationResult === "amount-is-too-small"
               ? i18n.str`Amount needs to be higher`
               : Amounts.isZero(calc.credit)
                 ? i18n.str`The total transfer at destination will be zero`
                 : undefined,
-    channel: OLD_CASHOUT_API && !form.channel ? i18n.str`Required` : undefined,
   });
   const trimmedAmountStr = form.amount?.trim();
 
@@ -260,9 +255,7 @@ export function CreateCashout({
     const request_uid = encodeCrock(getRandomBytes(32));
     await handleError(async () => {
       // new cashout api doesn't require channel
-      const validChannel =
-        !OLD_CASHOUT_API ||
-        config.supported_tan_channels.length === 0 ||
+      const validChannel = config.supported_tan_channels.length === 0 ||
         form.channel;
 
       if (!creds || !form.subject || !validChannel) return;
@@ -613,9 +606,9 @@ export function CreateCashout({
                       cashoutDisabled
                         ? undefined
                         : (value) => {
-                            form.amount = value;
-                            updateForm(structuredClone(form));
-                          }
+                          form.amount = value;
+                          updateForm(structuredClone(form));
+                        }
                     }
                   />
                   <ShowInputErrorLabel
@@ -656,7 +649,7 @@ export function CreateCashout({
                       </dd>
                     </div>
                     {Amounts.isZero(sellFee) ||
-                    Amounts.isZero(calc.beforeFee) ? undefined : (
+                      Amounts.isZero(calc.beforeFee) ? undefined : (
                       <div class="flex items-center justify-between border-t-2 
afu pt-4">
                         <dt class="flex items-center text-sm text-gray-600">
                           <span>
@@ -687,130 +680,6 @@ export function CreateCashout({
                 </div>
               )}
 
-              {/* channel, not shown if new cashout api */}
-              {!OLD_CASHOUT_API ? undefined : config.supported_tan_channels
-                  .length === 0 ? (
-                <div class="sm:col-span-5">
-                  <Attention
-                    type="warning"
-                    title={i18n.str`No cashout channel available`}
-                  >
-                    <i18n.Translate>
-                      Before doing a cashout the server need to provide an
-                      second channel to confirm the operation
-                    </i18n.Translate>
-                  </Attention>
-                </div>
-              ) : (
-                <div class="sm:col-span-5">
-                  <label
-                    class="block text-sm font-medium leading-6 text-gray-900"
-                    for="channel"
-                  >
-                    {i18n.str`Second factor authentication`}
-                  </label>
-                  <div class="mt-2 max-w-xl text-sm text-gray-500">
-                    <div class="px-4 mt-4 grid grid-cols-1 gap-y-6">
-                      {config.supported_tan_channels.indexOf(
-                        TanChannel.EMAIL,
-                      ) === -1 ? undefined : (
-                        <label
-                          onClick={() => {
-                            if (!resultAccount.body.contact_data?.email) 
return;
-                            form.channel = TanChannel.EMAIL;
-                            updateForm(structuredClone(form));
-                          }}
-                          data-disabled={
-                            !resultAccount.body.contact_data?.email
-                          }
-                          data-selected={form.channel === TanChannel.EMAIL}
-                          class="relative flex 
data-[disabled=false]:cursor-pointer rounded-lg border bg-white 
data-[disabled=true]:bg-gray-200 p-4 shadow-sm focus:outline-none 
border-gray-300 data-[selected=true]:ring-2 
data-[selected=true]:ring-indigo-600"
-                        >
-                          <input
-                            type="radio"
-                            name="channel"
-                            value="Newsletter"
-                            class="sr-only"
-                          />
-                          <span class="flex flex-1">
-                            <span class="flex flex-col">
-                              <span
-                                id="project-type-0-label"
-                                class="block text-sm font-medium text-gray-900 
"
-                              >
-                                <i18n.Translate>Email</i18n.Translate>
-                              </span>
-                              {!resultAccount.body.contact_data?.email &&
-                                i18n.str`Add a email in your profile to enable 
this option`}
-                            </span>
-                          </span>
-                          <svg
-                            data-selected={form.channel === TanChannel.EMAIL}
-                            class="h-5 w-5 text-indigo-600 
data-[selected=false]:hidden"
-                            viewBox="0 0 20 20"
-                            fill="currentColor"
-                            aria-hidden="true"
-                          >
-                            <path
-                              fill-rule="evenodd"
-                              d="M10 18a8 8 0 100-16 8 8 0 000 
16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 
1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
-                              clip-rule="evenodd"
-                            />
-                          </svg>
-                        </label>
-                      )}
-
-                      {config.supported_tan_channels.indexOf(TanChannel.SMS) 
===
-                      -1 ? undefined : (
-                        <label
-                          onClick={() => {
-                            if (!resultAccount.body.contact_data?.phone) 
return;
-                            form.channel = TanChannel.SMS;
-                            updateForm(structuredClone(form));
-                          }}
-                          data-disabled={
-                            !resultAccount.body.contact_data?.phone
-                          }
-                          data-selected={form.channel === TanChannel.SMS}
-                          class="relative flex 
data-[disabled=false]:cursor-pointer rounded-lg border 
data-[disabled=true]:bg-gray-200 p-4 shadow-sm focus:outline-none 
border-gray-300 data-[selected=true]:ring-2 
data-[selected=true]:ring-indigo-600"
-                        >
-                          <input
-                            type="radio"
-                            name="channel"
-                            value="Existing Customers"
-                            class="sr-only"
-                          />
-                          <span class="flex flex-1">
-                            <span class="flex flex-col">
-                              <span
-                                id="project-type-1-label"
-                                class="block text-sm font-medium text-gray-900"
-                              >
-                                <i18n.Translate>SMS</i18n.Translate>
-                              </span>
-                              {!resultAccount.body.contact_data?.phone &&
-                                i18n.str`Add a phone number in your profile to 
enable this option`}
-                            </span>
-                          </span>
-                          <svg
-                            data-selected={form.channel === TanChannel.SMS}
-                            class="h-5 w-5 text-indigo-600 
data-[selected=false]:hidden"
-                            viewBox="0 0 20 20"
-                            fill="currentColor"
-                            aria-hidden="true"
-                          >
-                            <path
-                              fill-rule="evenodd"
-                              d="M10 18a8 8 0 100-16 8 8 0 000 
16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 
1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
-                              clip-rule="evenodd"
-                            />
-                          </svg>
-                        </label>
-                      )}
-                    </div>
-                  </div>
-                </div>
-              )}
             </div>
           </div>
 
diff --git a/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx 
b/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx
index 849da77aa..eaefeab12 100644
--- a/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx
+++ b/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx
@@ -29,7 +29,7 @@ import { VNode, h } from "preact";
 import { ErrorLoadingWithDebug } from 
"../../components/ErrorLoadingWithDebug.js";
 import { Time } from "../../components/Time.js";
 import { useCashoutDetails, useConversionInfo } from "../../hooks/regional.js";
-import { RouteDefinition } from "../../route.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
 import { RenderAmount } from "../PaytoWireTransferForm.js";
 
 interface Props {
@@ -138,7 +138,7 @@ export function ShowCashoutDetails({ id, routeClose }: 
Props): VNode {
                           timestamp={AbsoluteTime.fromProtocolTimestamp(
                             result.body.creation_time,
                           )}
-                          // relative={Duration.fromSpec({ days: 1 })}
+                        // relative={Duration.fromSpec({ days: 1 })}
                         />
                       </dd>
                     </div>
diff --git a/packages/bank-ui/src/settings.ts b/packages/bank-ui/src/settings.ts
index c7c56d299..49c8408ce 100644
--- a/packages/bank-ui/src/settings.ts
+++ b/packages/bank-ui/src/settings.ts
@@ -17,6 +17,7 @@
 import {
   Codec,
   buildCodecForObject,
+  canonicalizeBaseUrl,
   codecForBoolean,
   codecForMap,
   codecForString,
@@ -101,7 +102,11 @@ function buildDefaultBackendBaseURL(): string | undefined {
       window.location.pathname,
       window.location.origin,
     ).href;
-    return currentLocation.replace("/webui", "");
+    /**
+     * By default, bank backend serves the html content
+     * from the /webui root. 
+     */
+    return canonicalizeBaseUrl(currentLocation.replace("/webui", ""));
   }
-  return undefined;
+  throw Error("No default URL")
 }
diff --git a/packages/bank-ui/src/stories.test.ts 
b/packages/bank-ui/src/stories.test.ts
index 8ed00a1e6..2f3988e9a 100644
--- a/packages/bank-ui/src/stories.test.ts
+++ b/packages/bank-ui/src/stories.test.ts
@@ -23,13 +23,13 @@ import {
   TalerCorebankApi,
   setupI18n,
 } from "@gnu-taler/taler-util";
-import { parseGroupImport } from "@gnu-taler/web-util/browser";
+import { BankApiProviderTesting, parseGroupImport } from 
"@gnu-taler/web-util/browser";
 import * as tests from "@gnu-taler/web-util/testing";
 import * as components from "./components/index.examples.js";
 import * as pages from "./pages/index.stories.js";
 
 import { ComponentChildren, VNode, h as create } from "preact";
-import { BankCoreApiProviderTesting } from "./context/config.js";
+// import { BankCoreApiProviderTesting } from "./context/config.js";
 
 setupI18n("en", { en: {} });
 
@@ -72,10 +72,9 @@ function DefaultTestingContext(_props: { children: 
ComponentChildren }): VNode {
     default_debit_threshold: "ARS:10" as AmountString,
     version: "1:0:0",
   };
-  const ctx2 = create(BankCoreApiProviderTesting, {
+  const ctx2 = create(BankApiProviderTesting, {
     children: [],
-    state: cfg,
-    url: "http://localhost";,
+    value: cfg as any,
   });
   return ctx2;
 }
diff --git a/packages/merchant-backoffice-ui/copyleft-header.js 
b/packages/merchant-backoffice-ui/copyleft-header.js
index f0d755a0e..2589fdc92 100644
--- a/packages/merchant-backoffice-ui/copyleft-header.js
+++ b/packages/merchant-backoffice-ui/copyleft-header.js
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/AdminRoutes.tsx 
b/packages/merchant-backoffice-ui/src/AdminRoutes.tsx
index 70b28a838..36c9f39ea 100644
--- a/packages/merchant-backoffice-ui/src/AdminRoutes.tsx
+++ b/packages/merchant-backoffice-ui/src/AdminRoutes.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -17,7 +17,7 @@ import { h, VNode } from "preact";
 import { Router, route, Route } from "preact-router";
 import InstanceCreatePage from "./paths/admin/create/index.js";
 import InstanceListPage from "./paths/admin/list/index.js";
-import { InstancePaths } from "./InstanceRoutes.js";
+import { InstancePaths } from "./Rounting.js";
 
 export enum AdminPaths {
   list_instances = "/instances",
diff --git a/packages/merchant-backoffice-ui/src/Application.tsx 
b/packages/merchant-backoffice-ui/src/Application.tsx
index cf46a34d5..9e6a6179f 100644
--- a/packages/merchant-backoffice-ui/src/Application.tsx
+++ b/packages/merchant-backoffice-ui/src/Application.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -19,147 +19,120 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { HttpStatusCode, LibtoolVersion } from "@gnu-taler/taler-util";
+import { canonicalizeBaseUrl } from "@gnu-taler/taler-util";
 import {
-  ErrorType,
-  TranslationProvider,
-  useTranslationContext
+  BrowserHashNavigationProvider,
+  MerchantApiProvider,
+  TalerWalletIntegrationBrowserProvider,
+  TranslationProvider
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
-import { useMemo } from "preact/hooks";
-import { ApplicationReadyRoutes } from "./ApplicationReadyRoutes.js";
+import { useEffect, useState } from "preact/hooks";
+import { SWRConfig } from "swr";
+import { Routing } from "./Routing.js";
 import { Loading } from "./components/exception/loading.js";
-import {
-  NotConnectedAppMenu,
-  NotificationCard
-} from "./components/menu/index.js";
-import {
-  BackendContextProvider
-} from "./context/backend.js";
-import { ConfigContextProvider } from "./context/config.js";
-import { useBackendConfig } from "./hooks/backend.js";
+import { SettingsProvider } from "./context/settings.js";
 import { strings } from "./i18n/strings.js";
+import { MerchantUiSettings, buildDefaultBackendBaseURL, fetchSettings } from 
"./settings.js";
+const WITH_LOCAL_STORAGE_CACHE = false;
 
 export function Application(): VNode {
+  const [settings, setSettings] = useState<MerchantUiSettings>();
+  useEffect(() => {
+    fetchSettings(setSettings);
+  }, []);
+  if (!settings) return <Loading />;
+
+  const baseUrl = getInitialBackendBaseURL(settings.backendBaseURL);
   return (
-    <BackendContextProvider>
-      <TranslationProvider source={strings}>
-        <ApplicationStatusRoutes />
+    <SettingsProvider value={settings}>
+      <TranslationProvider
+        source={strings}
+        completeness={{
+          es: strings["es"].completeness,
+          de: strings["de"].completeness,
+        }}
+      >
+        <MerchantApiProvider baseUrl={new URL("/", baseUrl)} frameOnError={({ 
children }) => <div>{children}</div>}>
+          <SWRConfig
+            value={{
+              provider: WITH_LOCAL_STORAGE_CACHE
+                ? localStorageProvider
+                : undefined,
+              // normally, do not revalidate
+              revalidateOnFocus: false,
+              revalidateOnReconnect: false,
+              revalidateIfStale: false,
+              revalidateOnMount: undefined,
+              focusThrottleInterval: undefined,
+
+              // normally, do not refresh
+              refreshInterval: undefined,
+              dedupingInterval: 2000,
+              refreshWhenHidden: false,
+              refreshWhenOffline: false,
+
+              // ignore errors
+              shouldRetryOnError: false,
+              errorRetryCount: 0,
+              errorRetryInterval: undefined,
+
+              // do not go to loading again if already has data
+              keepPreviousData: true,
+            }}
+          >
+            <TalerWalletIntegrationBrowserProvider>
+              <BrowserHashNavigationProvider>
+                <Routing />
+              </BrowserHashNavigationProvider>
+            </TalerWalletIntegrationBrowserProvider>
+          </SWRConfig>
+        </MerchantApiProvider>
       </TranslationProvider>
-    </BackendContextProvider>
+    </SettingsProvider>
   );
 }
 
-/**
- * Check connection testing against /config
- * 
- * @returns 
- */
-function ApplicationStatusRoutes(): VNode {
-  const result = useBackendConfig();
-  const { i18n } = useTranslationContext();
-
-  const configData = result.ok && result.data
-    ? result.data
-    : undefined;
-  const ctx = useMemo(() => (configData), [configData]);
+function getInitialBackendBaseURL(
+  backendFromSettings: string | undefined,
+): string {
+  /**
+   * For testing purpose
+   */
+  const overrideUrl =
+    typeof localStorage !== "undefined"
+      ? localStorage.getItem("merchant-base-url")
+      : undefined;
+  let result: string;
 
-  if (!result.ok) {
-    if (result.loading) return <Loading />;
-    if (
-      result.type === ErrorType.CLIENT &&
-      result.status === HttpStatusCode.Unauthorized
-    ) {
-      return (
-        <Fragment>
-          <NotConnectedAppMenu title="Login" />
-          <NotificationCard
-            notification={{
-              message: i18n.str`Checking the /config endpoint got 
authorization error`,
-              type: "ERROR",
-              description: `The /config endpoint of the backend server should 
be accessible`,
-            }}
-          />
-        </Fragment>
+  if (overrideUrl) {
+    // testing/development path
+    result = overrideUrl;
+  } else {
+    // normal path
+    if (!backendFromSettings) {
+      console.error(
+        "ERROR: backendBaseURL was overridden by a setting file and missing. 
Setting value to 'window.origin'",
       );
+      result = buildDefaultBackendBaseURL();
+    } else {
+      result = backendFromSettings;
     }
-    if (
-      result.type === ErrorType.CLIENT &&
-      result.status === HttpStatusCode.NotFound
-    ) {
-      return (
-        <Fragment>
-          <NotConnectedAppMenu title="Error" />
-          <NotificationCard
-            notification={{
-              message: i18n.str`Could not find /config endpoint on this URL`,
-              type: "ERROR",
-              description: `Check the URL or contact the system 
administrator.`,
-            }}
-          />
-        </Fragment>
-      );
-    }
-    if (result.type === ErrorType.SERVER) {
-      <Fragment>
-        <NotConnectedAppMenu title="Error" />
-        <NotificationCard
-          notification={{
-            message: i18n.str`Server response with an error code`,
-            type: "ERROR",
-            description: i18n.str`Got message "${result.message}" from 
${result.info?.url}`,
-          }}
-        />
-      </Fragment>;
-    }
-    if (result.type === ErrorType.UNREADABLE) {
-      <Fragment>
-        <NotConnectedAppMenu title="Error" />
-        <NotificationCard
-          notification={{
-            message: i18n.str`Response from server is unreadable, http status: 
${result.status}`,
-            type: "ERROR",
-            description: i18n.str`Got message "${result.message}" from 
${result.info?.url}`,
-          }}
-        />
-      </Fragment>;
-    }
-    return (
-      <Fragment>
-        <NotConnectedAppMenu title="Error" />
-        <NotificationCard
-          notification={{
-            message: i18n.str`Unexpected Error`,
-            type: "ERROR",
-            description: i18n.str`Got message "${result.message}" from 
${result.info?.url}`,
-          }}
-        />
-      </Fragment>
-    );
   }
-
-  const SUPPORTED_VERSION = "8:1:4"
-  if (result.data && !LibtoolVersion.compare(
-    SUPPORTED_VERSION,
-    result.data.version,
-  )?.compatible) {
-    return <Fragment>
-      <NotConnectedAppMenu title="Error" />
-      <NotificationCard
-        notification={{
-          message: i18n.str`Incompatible version`,
-          type: "ERROR",
-          description: i18n.str`Merchant backend server version 
${result.data.version} is not compatible with the supported version 
${SUPPORTED_VERSION}`,
-        }}
-      />
-    </Fragment>
+  try {
+    return canonicalizeBaseUrl(result);
+  } catch (e) {
+    // fall back
+    return canonicalizeBaseUrl(window.origin);
   }
+}
 
-  return (
-    <div class="has-navbar-fixed-top">
-      <ConfigContextProvider value={ctx!}>
-        <ApplicationReadyRoutes />
-      </ConfigContextProvider>
-    </div>
-  );
+function localStorageProvider(): Map<unknown, unknown> {
+  const map = new Map(JSON.parse(localStorage.getItem("app-cache") || "[]"));
+
+  window.addEventListener("beforeunload", () => {
+    const appCache = JSON.stringify(Array.from(map.entries()));
+    localStorage.setItem("app-cache", appCache);
+  });
+  return map;
 }
diff --git a/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx 
b/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx
index 3dc34d1a9..7cbb47f68 100644
--- a/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx
+++ b/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -18,13 +18,13 @@
  *
  * @author Sebastian Javier Marchano (sebasjm)
  */
-import { HttpStatusCode, TranslatedString } from "@gnu-taler/taler-util";
+import { HttpStatusCode } from "@gnu-taler/taler-util";
 import { ErrorType, useTranslationContext } from "@gnu-taler/web-util/browser";
 import { createHashHistory } from "history";
 import { Fragment, VNode, h } from "preact";
 import { Route, Router, route } from "preact-router";
-import { useEffect, useErrorBoundary, useState } from "preact/hooks";
-import { InstanceRoutes } from "./InstanceRoutes.js";
+import { useState } from "preact/hooks";
+import { InstanceRoutes } from "./Rounting.js";
 import {
   NotConnectedAppMenu,
   NotYetReadyAppMenu,
diff --git a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx 
b/packages/merchant-backoffice-ui/src/Rounting.tsx
similarity index 83%
rename from packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
rename to packages/merchant-backoffice-ui/src/Rounting.tsx
index edc1d9a11..a10310aa8 100644
--- a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
+++ b/packages/merchant-backoffice-ui/src/Rounting.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -19,28 +19,28 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { TranslatedString } from "@gnu-taler/taler-util";
+import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
-  useTranslationContext
+  urlPattern,
+  useTranslationContext,
 } from "@gnu-taler/web-util/browser";
 import { format } from "date-fns";
 import { Fragment, FunctionComponent, VNode, h } from "preact";
 import { Route, Router, route } from "preact-router";
 import { useEffect, useErrorBoundary, useMemo, useState } from "preact/hooks";
 import { Loading } from "./components/exception/loading.js";
-import { Menu, NotificationCard } from "./components/menu/index.js";
+import {
+  Menu,
+  NotConnectedAppMenu,
+  NotificationCard,
+} from "./components/menu/index.js";
 import { InstanceContextProvider } from "./context/instance.js";
 import { LoginToken, MerchantBackend } from "./declaration.js";
 import { useInstanceBankAccounts } from "./hooks/bank.js";
-import {
-  useBackendDefaultToken,
-  useBackendInstanceToken,
-  useSimpleLocalStorage,
-} from "./hooks/index.js";
 import { useInstanceKYCDetails } from "./hooks/instance.js";
-import { dateFormatForSettings, useSettings } from "./hooks/useSettings.js";
+import { dateFormatForSettings, usePreference } from "./hooks/preference.js";
 import InstanceCreatePage from "./paths/admin/create/index.js";
 import InstanceListPage from "./paths/admin/list/index.js";
 import BankAccountCreatePage from "./paths/instance/accounts/create/index.js";
@@ -75,6 +75,7 @@ import { LoginPage } from "./paths/login/index.js";
 import NotFoundPage from "./paths/notfound/index.js";
 import { Settings } from "./paths/settings/index.js";
 import { Notification } from "./utils/types.js";
+import { useSessionState } from "./hooks/session.js";
 
 export enum InstancePaths {
   error = "/error",
@@ -120,7 +121,7 @@ export enum InstancePaths {
 }
 
 // eslint-disable-next-line @typescript-eslint/no-empty-function
-const noop = () => { };
+const noop = () => {};
 
 export enum AdminPaths {
   list_instances = "/instances",
@@ -128,46 +129,44 @@ export enum AdminPaths {
   update_instance = "/instance/:id/update",
 }
 
-export interface Props {
-  id: string;
-  admin?: boolean;
-  path: string;
-  onUnauthorized: () => void;
-  onLoginPass: () => void;
-  setInstanceName: (s: string) => void;
-}
+export interface Props {}
 
-export function InstanceRoutes({
-  id,
-  admin,
-  path,
-  // onUnauthorized,
-  onLoginPass,
-  setInstanceName,
-}: Props): VNode {
-  const [defaultToken, updateDefaultToken] = useBackendDefaultToken();
-  const [token, updateToken] = useBackendInstanceToken(id);
+export const privatePages = {
+  home: urlPattern(/\/home/, () => "#/home"),
+  go: urlPattern(/\/home/, () => "#/home"),
+};
+export const publicPages = {
+  home: urlPattern(/\/home/, () => "#/home"),
+  go: urlPattern(/\/home/, () => "#/home"),
+};
+
+export function Routing(_p: Props): VNode {
   const { i18n } = useTranslationContext();
+  const { state } = useSessionState();
+  const admin = state.isAdmin;
+  const id = state.instance;
 
-  type GlobalNotifState = (Notification & { to: string | undefined }) | 
undefined;
+  type GlobalNotifState =
+    | (Notification & { to: string | undefined })
+    | undefined;
   const [globalNotification, setGlobalNotification] =
     useState<GlobalNotifState>(undefined);
 
-  const changeToken = (token?: LoginToken) => {
-    if (admin) {
-      updateToken(token);
-    } else {
-      updateDefaultToken(token);
-    }
-    onLoginPass()
-  };
+  // const changeToken = (token?: LoginToken) => {
+  //   if (admin) {
+  //     updateToken(token);
+  //   } else {
+  //     updateDefaultToken(token);
+  //   }
+  //   onLoginPass();
+  // };
 
   const [error] = useErrorBoundary();
 
-  const value = useMemo(
-    () => ({ id, token, admin, changeToken }),
-    [id, token, admin],
-  );
+  // const value = useMemo(
+  //   () => ({ id, token, admin, changeToken }),
+  //   [id, token, admin],
+  // );
 
   const instance = useInstanceBankAccounts();
   const accounts = !instance.ok ? undefined : instance.data.accounts;
@@ -201,20 +200,21 @@ export function InstanceRoutes({
 
   // const LoginPageAccessDeniend = onUnauthorized
   const LoginPageAccessDenied = () => {
-    return <Fragment>
-      <NotificationCard
-        notification={{
-          message: i18n.str`Access denied`,
-          description: i18n.str`Session expired or password changed.`,
-          type: "ERROR",
-        }}
-      />
-      <LoginPage onConfirm={changeToken} />
-    </Fragment>
-
-  }
+    return (
+      <Fragment>
+        <NotificationCard
+          notification={{
+            message: i18n.str`Access denied`,
+            description: i18n.str`Session expired or password changed.`,
+            type: "ERROR",
+          }}
+        />
+        <LoginPage />
+      </Fragment>
+    );
+  };
 
-  function IfAdminCreateDefaultOr<T>(Next: FunctionComponent<any>) {
+  function IfAdminCreateDefaultOr<T>(Next: FunctionComponent<unknown>) {
     return function IfAdminCreateDefaultOrImpl(props?: T) {
       if (admin && id === "default") {
         return (
@@ -245,39 +245,52 @@ export function InstanceRoutes({
   const clearTokenAndGoToRoot = () => {
     route("/");
     // clear all tokens
-    updateToken(undefined)
-    updateDefaultToken(undefined)
+    updateToken(undefined);
+    updateDefaultToken(undefined);
   };
 
+  if (state.status === "loggedOut" || state.status === "expired") {
+    return (
+      <Fragment>
+        <NotConnectedAppMenu title="Welcome!" />
+        <LoginPage />
+      </Fragment>
+    );
+  }
+
   if (accounts !== undefined && !admin && accounts.length < 1) {
-    return <InstanceContextProvider value={value}>
-      <Menu
-        instance={id}
-        admin={admin}
-        onShowSettings={() => {
-          route(InstancePaths.interface)
-        }}
-        path={path}
-        onLogout={clearTokenAndGoToRoot}
-        setInstanceName={setInstanceName}
-        isPasswordOk={defaultToken !== undefined}
-      />
-      <NotificationCard notification={{
-        type: "INFO",
-        message: i18n.str`You need to associate a bank account to receive 
revenue.`,
-        description: i18n.str`Without this the merchant backend will refuse to 
create new orders.`
-      }} />
-      <BankAccountCreatePage onConfirm={() => { }} />
-    </InstanceContextProvider>
+    return (
+      <Fragment>
+        <Menu
+          instance={id}
+          admin={admin}
+          onShowSettings={() => {
+            route(InstancePaths.interface);
+          }}
+          path={path}
+          onLogout={clearTokenAndGoToRoot}
+          setInstanceName={setInstanceName}
+          isPasswordOk={defaultToken !== undefined}
+        />
+        <NotificationCard
+          notification={{
+            type: "INFO",
+            message: i18n.str`You need to associate a bank account to receive 
revenue.`,
+            description: i18n.str`Without this the merchant backend will 
refuse to create new orders.`,
+          }}
+        />
+        <BankAccountCreatePage onConfirm={() => {}} />
+      </Fragment>
+    );
   }
 
   return (
-    <InstanceContextProvider value={value}>
+    <Fragment>
       <Menu
         instance={id}
         admin={admin}
         onShowSettings={() => {
-          route(InstancePaths.interface)
+          route(InstancePaths.interface);
         }}
         path={path}
         onLogout={clearTokenAndGoToRoot}
@@ -286,15 +299,23 @@ export function InstanceRoutes({
       />
       <KycBanner />
       <NotificationCard notification={globalNotification} />
-      {error &&
-        <NotificationCard notification={{
-          message: "Internal error, please repot",
-          type: "ERROR",
-          description: <pre>
-            {(error instanceof Error ? error.stack : String(error)) as 
TranslatedString}
-          </pre>
-        }} />
-      }
+      {error && (
+        <NotificationCard
+          notification={{
+            message: "Internal error, please repot",
+            type: "ERROR",
+            description: (
+              <pre>
+                {
+                  (error instanceof Error
+                    ? error.stack
+                    : String(error)) as TranslatedString
+                }
+              </pre>
+            ),
+          }}
+        />
+      )}
 
       <Router
         onChange={(e) => {
@@ -374,7 +395,7 @@ export function InstanceRoutes({
             route(`/`);
           }}
           onCancel={() => {
-            route(InstancePaths.order_list)
+            route(InstancePaths.order_list);
           }}
           onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
           onUnauthorized={LoginPageAccessDenied}
@@ -672,7 +693,7 @@ export function InstanceRoutes({
         <Route path="/loading" component={Loading} />
         <Route default component={NotFoundPage} />
       </Router>
-    </InstanceContextProvider>
+    </Fragment>
   );
 }
 
@@ -687,18 +708,10 @@ function AdminInstanceUpdatePage({
   id,
   ...rest
 }: { id: string } & InstanceUpdatePageProps): VNode {
-  const [token, changeToken] = useBackendInstanceToken(id);
-  const updateLoginStatus = (token?: LoginToken): void => {
-    changeToken(token);
-  };
-  const value = useMemo(
-    () => ({ id, token, admin: true, changeToken }),
-    [id, token],
-  );
   const { i18n } = useTranslationContext();
 
   return (
-    <InstanceContextProvider value={value}>
+    <Fragment>
       <InstanceAdminUpdatePage
         {...rest}
         instanceId={id}
@@ -706,24 +719,24 @@ function AdminInstanceUpdatePage({
           const notif =
             error.type === ErrorType.TIMEOUT
               ? {
-                message: i18n.str`The request to the backend take too long and 
was cancelled`,
-                description: i18n.str`Diagnostic from ${error.info.url} is 
'${error.message}'`,
-                type: "ERROR" as const,
-              }
+                  message: i18n.str`The request to the backend take too long 
and was cancelled`,
+                  description: i18n.str`Diagnostic from ${error.info.url} is 
'${error.message}'`,
+                  type: "ERROR" as const,
+                }
               : {
-                message: i18n.str`The backend reported a problem: HTTP status 
#${error.status}`,
-                description: i18n.str`Diagnostic from ${error.info.url} is 
'${error.message}'`,
-                details:
-                  error.type === ErrorType.CLIENT ||
+                  message: i18n.str`The backend reported a problem: HTTP 
status #${error.status}`,
+                  description: i18n.str`Diagnostic from ${error.info.url} is 
'${error.message}'`,
+                  details:
+                    error.type === ErrorType.CLIENT ||
                     error.type === ErrorType.SERVER
-                    ? error.payload.detail
-                    : undefined,
-                type: "ERROR" as const,
-              };
+                      ? error.payload.detail
+                      : undefined,
+                  type: "ERROR" as const,
+                };
           return (
             <Fragment>
               <NotificationCard notification={notif} />
-              <LoginPage onConfirm={updateLoginStatus} />
+              <LoginPage />
             </Fragment>
           );
         }}
@@ -737,24 +750,31 @@ function AdminInstanceUpdatePage({
                   type: "ERROR",
                 }}
               />
-              <LoginPage onConfirm={updateLoginStatus} />
+              <LoginPage />
             </Fragment>
           );
         }}
       />
-    </InstanceContextProvider>
+    </Fragment>
   );
 }
 
 function KycBanner(): VNode {
   const kycStatus = useInstanceKYCDetails();
   const { i18n } = useTranslationContext();
-  const [settings] = useSettings();
-  const today = format(new Date(), dateFormatForSettings(settings));
-  const [lastHide, setLastHide] = useSimpleLocalStorage("kyc-last-hide");
-  const hasBeenHidden = today === lastHide;
+  // const today = format(new Date(), dateFormatForSettings(settings));
+  const [prefs, updatePref] = usePreference();
+
+  const now = AbsoluteTime.now();
+
   const needsToBeShown = kycStatus.ok && kycStatus.data.type === "redirect";
-  if (hasBeenHidden || !needsToBeShown) return <Fragment />;
+
+  const hidden = AbsoluteTime.cmp(now, prefs.hideKycUntil) < 1;
+  if (hidden || !needsToBeShown) return <Fragment />;
+
+  const oneDay = { d_ms: 1000 * 60 * 60 * 24 };
+  const tomorrow = AbsoluteTime.addDuration(now, oneDay);
+  
   return (
     <NotificationCard
       notification={{
@@ -767,7 +787,10 @@ function KycBanner(): VNode {
               the KYC section in the left panel for more information
             </p>
             <div class="buttons is-right">
-              <button class="button" onClick={() => setLastHide(today)}>
+              <button
+                class="button"
+                onClick={() => updatePref("hideKycUntil", tomorrow)}
+              >
                 <i18n.Translate>Hide for today</i18n.Translate>
               </button>
             </div>
diff --git 
a/packages/merchant-backoffice-ui/src/components/exception/AsyncButton.tsx 
b/packages/merchant-backoffice-ui/src/components/exception/AsyncButton.tsx
index b1fc33877..58c10e7d7 100644
--- a/packages/merchant-backoffice-ui/src/components/exception/AsyncButton.tsx
+++ b/packages/merchant-backoffice-ui/src/components/exception/AsyncButton.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/exception/QR.tsx 
b/packages/merchant-backoffice-ui/src/components/exception/QR.tsx
index c9340ea76..246ce0229 100644
--- a/packages/merchant-backoffice-ui/src/components/exception/QR.tsx
+++ b/packages/merchant-backoffice-ui/src/components/exception/QR.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/exception/loading.tsx 
b/packages/merchant-backoffice-ui/src/components/exception/loading.tsx
index a043b81eb..5c249f79d 100644
--- a/packages/merchant-backoffice-ui/src/components/exception/loading.tsx
+++ b/packages/merchant-backoffice-ui/src/components/exception/loading.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/FormProvider.tsx 
b/packages/merchant-backoffice-ui/src/components/form/FormProvider.tsx
index 0d53c4d08..a5f3c1d2f 100644
--- a/packages/merchant-backoffice-ui/src/components/form/FormProvider.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/FormProvider.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/form/Input.tsx 
b/packages/merchant-backoffice-ui/src/components/form/Input.tsx
index c1ddcb064..899061c35 100644
--- a/packages/merchant-backoffice-ui/src/components/form/Input.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/Input.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputArray.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputArray.tsx
index 4ed4c4b28..b0b9eaefc 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputArray.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputArray.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputBoolean.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputBoolean.tsx
index f79e16c07..bdb2feb6b 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputBoolean.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputBoolean.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx
index b02354d7c..c1359e641 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputDate.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputDate.tsx
index a398629dc..812505f6a 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputDate.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputDate.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -24,7 +24,7 @@ import { ComponentChildren, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { DatePicker } from "../picker/DatePicker.js";
 import { InputProps, useField } from "./useField.js";
-import { dateFormatForSettings, useSettings } from 
"../../hooks/useSettings.js";
+import { dateFormatForSettings, usePreference } from 
"../../hooks/preference.js";
 
 export interface Props<T> extends InputProps<T> {
   readonly?: boolean;
@@ -47,7 +47,7 @@ export function InputDate<T>({
 }: Props<keyof T>): VNode {
   const [opened, setOpened] = useState(false);
   const { i18n } = useTranslationContext();
-  const [settings] = useSettings()
+  const [settings] = usePreference()
 
   const { error, required, value, onChange } = useField<T>(name);
 
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx
index c9226ad69..ad3cb0e32 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputGroup.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputGroup.tsx
index b5e0bd52b..92b9e8b16 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputGroup.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputGroup.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx
index b024e2c6b..d284b476f 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputLocation.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputLocation.tsx
index a2fc8113e..d4b13d555 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputLocation.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputLocation.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx
index 3b5df1474..10b28cd93 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputPayto.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputPayto.tsx
index 6e88e8f2c..fcecd8932 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputPayto.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputPayto.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.stories.tsx
 
b/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.stories.tsx
index 282e52278..cc5326bbe 100644
--- 
a/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx
index 32545c89a..7eba8b0b5 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputSearchOnList.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputSearchOnList.tsx
index be5800d14..9956a6427 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputSearchOnList.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputSearchOnList.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputSecured.stories.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputSecured.stories.tsx
index 12ce6c6aa..4de84d984 100644
--- 
a/packages/merchant-backoffice-ui/src/components/form/InputSecured.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/components/form/InputSecured.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputSecured.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputSecured.tsx
index 9d1a3ab8e..4a35ad96c 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputSecured.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputSecured.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputSelector.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputSelector.tsx
index a8dad5d89..f567f7247 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputSelector.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputSelector.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputStock.stories.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputStock.stories.tsx
index 668c65ea7..d7cf04553 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputStock.stories.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputStock.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx
index 1d18685c5..5c98f7311 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputTab.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputTab.tsx
index 2701768aa..1cd88d31a 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputTab.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputTab.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputTaxes.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputTaxes.tsx
index b5722e4ec..984b496e7 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputTaxes.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputTaxes.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputToggle.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputToggle.tsx
index f95dfcd05..89b815b4b 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputToggle.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputToggle.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx
index e9fd88770..b8cd4c2d2 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/form/TextField.tsx 
b/packages/merchant-backoffice-ui/src/components/form/TextField.tsx
index 03f36dcbb..8f897c2d8 100644
--- a/packages/merchant-backoffice-ui/src/components/form/TextField.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/TextField.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/form/useField.tsx 
b/packages/merchant-backoffice-ui/src/components/form/useField.tsx
index c7559faae..49bba4984 100644
--- a/packages/merchant-backoffice-ui/src/components/form/useField.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/useField.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/useGroupField.tsx 
b/packages/merchant-backoffice-ui/src/components/form/useGroupField.tsx
index 9a445eb32..4fbfc4a75 100644
--- a/packages/merchant-backoffice-ui/src/components/form/useGroupField.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/useGroupField.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/index.stories.ts 
b/packages/merchant-backoffice-ui/src/components/index.stories.ts
index c57ddab14..f96defc09 100644
--- a/packages/merchant-backoffice-ui/src/components/index.stories.ts
+++ b/packages/merchant-backoffice-ui/src/components/index.stories.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx
 
b/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx
index 6f5881fc0..e36549e76 100644
--- 
a/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx
+++ 
b/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/menu/LangSelector.tsx 
b/packages/merchant-backoffice-ui/src/components/menu/LangSelector.tsx
index 41fe1374a..a6cd8014d 100644
--- a/packages/merchant-backoffice-ui/src/components/menu/LangSelector.tsx
+++ b/packages/merchant-backoffice-ui/src/components/menu/LangSelector.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx 
b/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx
index 9f1b33893..d81410bdf 100644
--- a/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx
+++ b/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx 
b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
index 3146cf5e9..92551cc4c 100644
--- a/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
+++ b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/components/menu/index.tsx 
b/packages/merchant-backoffice-ui/src/components/menu/index.tsx
index 7bb7c0c00..57d401ffa 100644
--- a/packages/merchant-backoffice-ui/src/components/menu/index.tsx
+++ b/packages/merchant-backoffice-ui/src/components/menu/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -17,7 +17,7 @@
 import { ComponentChildren, Fragment, h, VNode } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import { AdminPaths } from "../../AdminRoutes.js";
-import { InstancePaths } from "../../InstanceRoutes.js";
+import { InstancePaths } from "../../Rounting.js";
 import { Notification } from "../../utils/types.js";
 import { NavigationBar } from "./NavigationBar.js";
 import { Sidebar } from "./SideBar.js";
@@ -79,13 +79,10 @@ function getAdminTitle(path: string, instance: string) {
 
 interface MenuProps {
   title?: string;
-  path: string;
   instance: string;
   admin?: boolean;
   onLogout?: () => void;
   onShowSettings: () => void;
-  setInstanceName: (s: string) => void;
-  isPasswordOk: boolean;
 }
 
 function WithTitle({
diff --git a/packages/merchant-backoffice-ui/src/components/modal/index.tsx 
b/packages/merchant-backoffice-ui/src/components/modal/index.tsx
index 8372c84cc..c684ba7a3 100644
--- a/packages/merchant-backoffice-ui/src/components/modal/index.tsx
+++ b/packages/merchant-backoffice-ui/src/components/modal/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/notifications/CreatedSuccessfully.tsx
 
b/packages/merchant-backoffice-ui/src/components/notifications/CreatedSuccessfully.tsx
index 073382fb1..5cd8a237b 100644
--- 
a/packages/merchant-backoffice-ui/src/components/notifications/CreatedSuccessfully.tsx
+++ 
b/packages/merchant-backoffice-ui/src/components/notifications/CreatedSuccessfully.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/notifications/Notifications.stories.tsx
 
b/packages/merchant-backoffice-ui/src/components/notifications/Notifications.stories.tsx
index af594de0f..d75c5ced2 100644
--- 
a/packages/merchant-backoffice-ui/src/components/notifications/Notifications.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/components/notifications/Notifications.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/notifications/index.tsx 
b/packages/merchant-backoffice-ui/src/components/notifications/index.tsx
index 235c75577..0c4e0d761 100644
--- a/packages/merchant-backoffice-ui/src/components/notifications/index.tsx
+++ b/packages/merchant-backoffice-ui/src/components/notifications/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/picker/DatePicker.tsx 
b/packages/merchant-backoffice-ui/src/components/picker/DatePicker.tsx
index 0bc629d46..d637958cb 100644
--- a/packages/merchant-backoffice-ui/src/components/picker/DatePicker.tsx
+++ b/packages/merchant-backoffice-ui/src/components/picker/DatePicker.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.stories.tsx
 
b/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.stories.tsx
index 8f74d55ac..b95ab054c 100644
--- 
a/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx 
b/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx
index ba003cce5..7c1c172ac 100644
--- a/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx
+++ b/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.stories.tsx
 
b/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.stories.tsx
index 2d5a54cde..fcc97f96a 100644
--- 
a/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.tsx
 
b/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.tsx
index 377d9c1ba..25b1f0e2d 100644
--- 
a/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.tsx
+++ 
b/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/NonInventoryProductForm.tsx
 
b/packages/merchant-backoffice-ui/src/components/product/NonInventoryProductForm.tsx
index c6d280f94..8ddd9fa95 100644
--- 
a/packages/merchant-backoffice-ui/src/components/product/NonInventoryProductForm.tsx
+++ 
b/packages/merchant-backoffice-ui/src/components/product/NonInventoryProductForm.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx 
b/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx
index e91e8c876..47e3431e2 100644
--- a/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx
+++ b/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/ProductList.tsx 
b/packages/merchant-backoffice-ui/src/components/product/ProductList.tsx
index 25751dd96..d89c5371b 100644
--- a/packages/merchant-backoffice-ui/src/components/product/ProductList.tsx
+++ b/packages/merchant-backoffice-ui/src/components/product/ProductList.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/context/backend.test.ts 
b/packages/merchant-backoffice-ui/src/context/backend.test.ts
index 359859819..74530e750 100644
--- a/packages/merchant-backoffice-ui/src/context/backend.test.ts
+++ b/packages/merchant-backoffice-ui/src/context/backend.test.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/context/backend.ts 
b/packages/merchant-backoffice-ui/src/context/backend.ts
index 6f2fd2aff..f78236216 100644
--- a/packages/merchant-backoffice-ui/src/context/backend.ts
+++ b/packages/merchant-backoffice-ui/src/context/backend.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -53,7 +53,7 @@ function useBackendContextState(
   };
 }
 
-export const BackendContextProvider = ({
+const BackendContextProvider = ({
   children,
   defaultUrl,
 }: {
@@ -65,5 +65,5 @@ export const BackendContextProvider = ({
   return h(BackendContext.Provider, { value, children });
 };
 
-export const useBackendContext = (): BackendContextType =>
+const useBackendContext = (): BackendContextType =>
   useContext(BackendContext);
diff --git a/packages/merchant-backoffice-ui/src/context/config.ts 
b/packages/merchant-backoffice-ui/src/context/config.ts
index 9fe655301..8c562b3c1 100644
--- a/packages/merchant-backoffice-ui/src/context/config.ts
+++ b/packages/merchant-backoffice-ui/src/context/config.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/context/instance.ts 
b/packages/merchant-backoffice-ui/src/context/instance.ts
index 3c6cc2b63..f969a99d6 100644
--- a/packages/merchant-backoffice-ui/src/context/instance.ts
+++ b/packages/merchant-backoffice-ui/src/context/instance.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -32,5 +32,5 @@ interface Type {
 
 const Context = createContext<Type>({} as any);
 
-export const InstanceContextProvider = Context.Provider;
-export const useInstanceContext = (): Type => useContext(Context);
+const InstanceContextProvider = Context.Provider;
+const useInstanceContext = (): Type => useContext(Context);
diff --git a/packages/merchant-backoffice-ui/src/context/instance.ts 
b/packages/merchant-backoffice-ui/src/context/settings.ts
similarity index 58%
copy from packages/merchant-backoffice-ui/src/context/instance.ts
copy to packages/merchant-backoffice-ui/src/context/settings.ts
index 3c6cc2b63..8bd1506d6 100644
--- a/packages/merchant-backoffice-ui/src/context/instance.ts
+++ b/packages/merchant-backoffice-ui/src/context/settings.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -14,23 +14,31 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
+import { ComponentChildren, createContext, h, VNode } from "preact";
+import { useContext } from "preact/hooks";
+import { MerchantUiSettings } from "../settings.js";
+
 /**
  *
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { createContext } from "preact";
-import { useContext } from "preact/hooks";
-import { LoginToken } from "../declaration.js";
-
-interface Type {
-  id: string;
-  token?: LoginToken;
-  admin?: boolean;
-  changeToken: (t?: LoginToken) => void;
-}
-
-const Context = createContext<Type>({} as any);
-
-export const InstanceContextProvider = Context.Provider;
-export const useInstanceContext = (): Type => useContext(Context);
+export type Type = MerchantUiSettings;
+
+const initial: MerchantUiSettings = {};
+const Context = createContext<Type>(initial);
+
+export const useSettingsContext = (): Type => useContext(Context);
+
+export const SettingsProvider = ({
+  children,
+  value,
+}: {
+  value: MerchantUiSettings;
+  children: ComponentChildren;
+}): VNode => {
+  return h(Context.Provider, {
+    value,
+    children,
+  });
+};
diff --git a/packages/merchant-backoffice-ui/src/custom.d.ts 
b/packages/merchant-backoffice-ui/src/custom.d.ts
index e693c2951..34522a2dd 100644
--- a/packages/merchant-backoffice-ui/src/custom.d.ts
+++ b/packages/merchant-backoffice-ui/src/custom.d.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/declaration.d.ts 
b/packages/merchant-backoffice-ui/src/declaration.d.ts
index d716fe132..ff526282a 100644
--- a/packages/merchant-backoffice-ui/src/declaration.d.ts
+++ b/packages/merchant-backoffice-ui/src/declaration.d.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/async.ts 
b/packages/merchant-backoffice-ui/src/hooks/async.ts
index f22badc88..212ef2211 100644
--- a/packages/merchant-backoffice-ui/src/hooks/async.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/async.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/backend.ts 
b/packages/merchant-backoffice-ui/src/hooks/backend.ts
index 292261bc8..4305a9309 100644
--- a/packages/merchant-backoffice-ui/src/hooks/backend.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/backend.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/bank.ts 
b/packages/merchant-backoffice-ui/src/hooks/bank.ts
index 5d5785442..d01b579b9 100644
--- a/packages/merchant-backoffice-ui/src/hooks/bank.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/bank.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/index.ts 
b/packages/merchant-backoffice-ui/src/hooks/index.ts
index 9c194fdee..cb58cf066 100644
--- a/packages/merchant-backoffice-ui/src/hooks/index.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/index.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -21,10 +21,9 @@
 
 import { buildCodecForObject, codecForMap, codecForString, codecForTimestamp } 
from "@gnu-taler/taler-util";
 import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";
-import { StateUpdater, useEffect, useState } from "preact/hooks";
+import { StateUpdater, useState } from "preact/hooks";
 import { LoginToken } from "../declaration.js";
 import { ValueOrFunction } from "../utils/types.js";
-import { useMatchMutate } from "./backend.js";
 
 const calculateRootPath = () => {
   const rootPath =
@@ -48,7 +47,7 @@ const loginTokenCodec = buildCodecForObject<LoginToken>()
 const TOKENS_KEY = buildStorageKey("merchant-token", 
codecForMap(loginTokenCodec));
 
 
-export function useBackendURL(
+function useBackendURL(
   url?: string,
 ): [string, StateUpdater<string>] {
   const [value, setter] = useSimpleLocalStorage(
@@ -63,7 +62,7 @@ export function useBackendURL(
   return [value!, checkedSetter];
 }
 
-export function useBackendDefaultToken(
+function useBackendDefaultToken(
 ): [LoginToken | undefined, ((d: LoginToken | undefined) => void)] {
   const { update: setToken, value: tokenMap, reset } = 
useLocalStorage(TOKENS_KEY, {})
 
@@ -86,7 +85,7 @@ export function useBackendDefaultToken(
   return [tokenMap["default"], updateToken];
 }
 
-export function useBackendInstanceToken(
+function useBackendInstanceToken(
   id: string,
 ): [LoginToken | undefined, ((d: LoginToken | undefined) => void)] {
   const { update: setToken, value: tokenMap, reset } = 
useLocalStorage(TOKENS_KEY, {})
@@ -110,7 +109,7 @@ export function useBackendInstanceToken(
   return [tokenMap[id], updateToken];
 }
 
-export function useLang(initial?: string): [string, StateUpdater<string>] {
+function useLang(initial?: string): [string, StateUpdater<string>] {
   const browserLang =
     typeof window !== "undefined"
       ? navigator.language || (navigator as any).userLanguage
@@ -119,7 +118,7 @@ export function useLang(initial?: string): [string, 
StateUpdater<string>] {
   return useSimpleLocalStorage("lang-preference", defaultLang) as [string, 
StateUpdater<string>];
 }
 
-export function useSimpleLocalStorage(
+function useSimpleLocalStorage(
   key: string,
   initialValue?: string,
 ): [string | undefined, StateUpdater<string | undefined>] {
diff --git a/packages/merchant-backoffice-ui/src/hooks/instance.test.ts 
b/packages/merchant-backoffice-ui/src/hooks/instance.test.ts
index ee1576764..4f6cabc9e 100644
--- a/packages/merchant-backoffice-ui/src/hooks/instance.test.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/instance.test.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/instance.ts 
b/packages/merchant-backoffice-ui/src/hooks/instance.ts
index 0677191db..352f54982 100644
--- a/packages/merchant-backoffice-ui/src/hooks/instance.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/instance.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/listener.ts 
b/packages/merchant-backoffice-ui/src/hooks/listener.ts
index d101f7bb8..f59794fd4 100644
--- a/packages/merchant-backoffice-ui/src/hooks/listener.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/listener.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/merchant.ts 
b/packages/merchant-backoffice-ui/src/hooks/merchant.ts
index 5d5785442..d01b579b9 100644
--- a/packages/merchant-backoffice-ui/src/hooks/merchant.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/merchant.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/notifications.ts 
b/packages/merchant-backoffice-ui/src/hooks/notifications.ts
index 133ddd80b..137ef5333 100644
--- a/packages/merchant-backoffice-ui/src/hooks/notifications.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/notifications.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/order.test.ts 
b/packages/merchant-backoffice-ui/src/hooks/order.test.ts
index c243309a8..86f53a342 100644
--- a/packages/merchant-backoffice-ui/src/hooks/order.test.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/order.test.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/order.ts 
b/packages/merchant-backoffice-ui/src/hooks/order.ts
index e7a893f2c..efc7bdcbe 100644
--- a/packages/merchant-backoffice-ui/src/hooks/order.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/order.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/otp.ts 
b/packages/merchant-backoffice-ui/src/hooks/otp.ts
index b045e365a..76ece7055 100644
--- a/packages/merchant-backoffice-ui/src/hooks/otp.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/otp.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/preference.ts 
b/packages/merchant-backoffice-ui/src/hooks/preference.ts
new file mode 100644
index 000000000..4570ff679
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/preference.ts
@@ -0,0 +1,85 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021-2024 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/>
+ */
+
+import {
+  AbsoluteTime,
+  Codec,
+  buildCodecForObject,
+  codecForAbsoluteTime,
+  codecForBoolean,
+  codecForConstString,
+  codecForEither,
+} from "@gnu-taler/taler-util";
+import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";
+
+export interface Preferences {
+  advanceOrderMode: boolean;
+  hideKycUntil: AbsoluteTime;
+  dateFormat: "ymd" | "dmy" | "mdy";
+}
+
+const defaultSettings: Preferences = {
+  advanceOrderMode: false,
+  hideKycUntil: AbsoluteTime.never(),
+  dateFormat: "ymd",
+};
+
+export const codecForPreferences = (): Codec<Preferences> =>
+  buildCodecForObject<Preferences>()
+    .property("advanceOrderMode", codecForBoolean())
+    .property("hideKycUntil", codecForAbsoluteTime)
+    .property(
+      "dateFormat",
+      codecForEither(
+        codecForConstString("ymd"),
+        codecForConstString("dmy"),
+        codecForConstString("mdy"),
+      ),
+    )
+    .build("Preferences");
+
+const PREFERENCES_KEY = buildStorageKey(
+  "merchant-preferences",
+  codecForPreferences(),
+);
+
+export function usePreference(): [
+  Readonly<Preferences>,
+  <T extends keyof Preferences>(key: T, value: Preferences[T]) => void,
+] {
+  const { value, update } = useLocalStorage(PREFERENCES_KEY, defaultSettings);
+  function updateField<T extends keyof Preferences>(k: T, v: Preferences[T]) {
+    const newValue = { ...value, [k]: v };
+    update(newValue);
+  }
+
+  return [value, updateField];
+}
+
+export function dateFormatForSettings(s: Preferences): string {
+  switch (s.dateFormat) {
+    case "ymd":
+      return "yyyy/MM/dd";
+    case "dmy":
+      return "dd/MM/yyyy";
+    case "mdy":
+      return "MM/dd/yyyy";
+  }
+}
+
+export function datetimeFormatForSettings(s: Preferences): string {
+  return dateFormatForSettings(s) + " HH:mm:ss";
+}
diff --git a/packages/merchant-backoffice-ui/src/hooks/product.test.ts 
b/packages/merchant-backoffice-ui/src/hooks/product.test.ts
index 7cac10e25..fd2b83ecc 100644
--- a/packages/merchant-backoffice-ui/src/hooks/product.test.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/product.test.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/product.ts 
b/packages/merchant-backoffice-ui/src/hooks/product.ts
index b54cd4d91..345ca5bf2 100644
--- a/packages/merchant-backoffice-ui/src/hooks/product.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/product.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/reserve.test.ts 
b/packages/merchant-backoffice-ui/src/hooks/reserve.test.ts
index 186af1f61..58472399f 100644
--- a/packages/merchant-backoffice-ui/src/hooks/reserve.test.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/reserve.test.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/reserves.ts 
b/packages/merchant-backoffice-ui/src/hooks/reserves.ts
index 62dc48412..13e4bcce8 100644
--- a/packages/merchant-backoffice-ui/src/hooks/reserves.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/reserves.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/session.ts 
b/packages/merchant-backoffice-ui/src/hooks/session.ts
new file mode 100644
index 000000000..7b06ea290
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/session.ts
@@ -0,0 +1,185 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021-2024 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/>
+ */
+
+import {
+  AccessToken,
+  Codec,
+  buildCodecForObject,
+  buildCodecForUnion,
+  codecForBoolean,
+  codecForConstString,
+  codecForConstTrue,
+  codecForString,
+  codecOptional,
+} from "@gnu-taler/taler-util";
+import { buildStorageKey, useLocalStorage, useMerchantApiContext } from 
"@gnu-taler/web-util/browser";
+import { mutate } from "swr";
+
+/**
+ * Has the information to reach and
+ * authenticate at the bank's backend.
+ */
+export type SessionState = LoggedIn | LoggedOut | Expired | Impersonate;
+
+interface LoggedIn {
+  status: "loggedIn";
+  instance: string;
+  isAdmin: boolean;
+  token: AccessToken | undefined;
+}
+interface Expired {
+  status: "expired";
+  instance: string;
+  isAdmin: boolean;
+}
+interface Impersonate {
+  status: "impersonate";
+  instance: string;
+  isAdmin: true;
+  token: AccessToken | undefined;
+  originalInstance: string;
+  originalToken: AccessToken | undefined;
+}
+interface LoggedOut {
+  status: "loggedOut";
+  instance: string;
+  isAdmin: boolean;
+}
+
+export const codecForSessionStateLoggedIn = (): Codec<LoggedIn> =>
+  buildCodecForObject<LoggedIn>()
+    .property("status", codecForConstString("loggedIn"))
+    .property("instance", codecForString())
+    .property("token", codecOptional(codecForString() as Codec<AccessToken>))
+    .property("isAdmin", codecForBoolean())
+    .build("SessionState.LoggedIn");
+
+export const codecForSessionStateExpired = (): Codec<Expired> =>
+  buildCodecForObject<Expired>()
+    .property("status", codecForConstString("expired"))
+    .property("instance", codecForString())
+    .property("isAdmin", codecForBoolean())
+    .build("SessionState.Expired");
+
+export const codecForSessionStateLoggedOut = (): Codec<LoggedOut> =>
+  buildCodecForObject<LoggedOut>()
+    .property("status", codecForConstString("loggedOut"))
+    .property("instance", codecForString())
+    .property("isAdmin", codecForBoolean())
+    .build("SessionState.LoggedOut");
+
+export const codecForSessionStateImpresonate = (): Codec<Impersonate> =>
+  buildCodecForObject<Impersonate>()
+    .property("status", codecForConstString("impersonate"))
+    .property("instance", codecForString())
+    .property("isAdmin", codecForConstTrue())
+    .property("token", codecOptional(codecForString() as Codec<AccessToken>))
+    .property("originalInstance", codecForString())
+    .property("originalToken", codecOptional(codecForString() as 
Codec<AccessToken>))
+    .build("SessionState.Impersonate");
+
+export const codecForSessionState = (): Codec<SessionState> =>
+  buildCodecForUnion<SessionState>()
+    .discriminateOn("status")
+    .alternative("loggedIn", codecForSessionStateLoggedIn())
+    .alternative("impersonate", codecForSessionStateImpresonate())
+    .alternative("loggedOut", codecForSessionStateLoggedOut())
+    .alternative("expired", codecForSessionStateExpired())
+    .build("SessionState");
+
+export const defaultState = (instance: string): SessionState => ({
+  status: "loggedIn",
+  instance,
+  isAdmin: instance === DEFAULT_ADMIN_USERNAME,
+  token: undefined,
+});
+
+export interface SessionStateHandler {
+  state: SessionState;
+  logOut(): void;
+  expired(): void;
+  logIn(info: { token: AccessToken }): void;
+  impersonate(info: { instance: string; token: AccessToken }): void;
+}
+
+const SESSION_STATE_KEY = buildStorageKey("merchant-session", 
codecForSessionState());
+
+export const DEFAULT_ADMIN_USERNAME = "default"
+
+export const INSTANCE_ID_LOOKUP = /\/instances\/([^/]*)\/?$/;
+
+/**
+ * Return getters and setters for
+ * login credentials and backend's
+ * base URL.
+ */
+export function useSessionState(): SessionStateHandler {
+  const { url } = useMerchantApiContext();
+
+  const match = INSTANCE_ID_LOOKUP.exec(url.href);
+  const instanceName = !match || !match[1] ? DEFAULT_ADMIN_USERNAME : match[1];
+
+  const { value: state, update } = useLocalStorage(
+    SESSION_STATE_KEY,
+    defaultState(instanceName),
+  );
+
+  return {
+    state,
+    logOut() {
+      update(defaultState(instanceName));
+    },
+    impersonate(info) {
+      if (state.status === "loggedOut" || state.status === "expired") {
+        // can't impersonate if not loggedin
+        return;
+      }
+      const nextState: SessionState = {
+        status: "impersonate",
+        originalToken: state.token,
+        originalInstance: state.instance,
+        isAdmin: true,
+        instance: info.instance,
+        token: info.token,
+      };
+      update(nextState);
+    },
+    expired() {
+      if (state.status === "loggedOut") return;
+      const nextState: SessionState = {
+        status: "expired",
+        instance: state.instance,
+        isAdmin: state.instance === DEFAULT_ADMIN_USERNAME,
+      };
+      update(nextState);
+    },
+    logIn(info) {
+      // admin is defined by the username
+      const nextState: SessionState = {
+        status: "loggedIn",
+        instance: state.instance,
+        token: info.token,
+        isAdmin: state.instance === DEFAULT_ADMIN_USERNAME,
+      };
+      update(nextState);
+      cleanAllCache();
+    },
+  };
+}
+
+function cleanAllCache(): void {
+  mutate(() => true, undefined, { revalidate: false });
+}
diff --git a/packages/merchant-backoffice-ui/src/hooks/templates.ts 
b/packages/merchant-backoffice-ui/src/hooks/templates.ts
index ee8728cc8..96671452e 100644
--- a/packages/merchant-backoffice-ui/src/hooks/templates.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/templates.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/testing.tsx 
b/packages/merchant-backoffice-ui/src/hooks/testing.tsx
index a0ba59b2e..d9a70e794 100644
--- a/packages/merchant-backoffice-ui/src/hooks/testing.tsx
+++ b/packages/merchant-backoffice-ui/src/hooks/testing.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts 
b/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts
index a7187af27..2fd11f02e 100644
--- a/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/transfer.ts 
b/packages/merchant-backoffice-ui/src/hooks/transfer.ts
index 27c3bdc75..924bd202f 100644
--- a/packages/merchant-backoffice-ui/src/hooks/transfer.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/transfer.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/urls.ts 
b/packages/merchant-backoffice-ui/src/hooks/urls.ts
index b6485259f..76c117224 100644
--- a/packages/merchant-backoffice-ui/src/hooks/urls.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/urls.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/hooks/useSettings.ts 
b/packages/merchant-backoffice-ui/src/hooks/useSettings.ts
deleted file mode 100644
index 8c1ebd9f6..000000000
--- a/packages/merchant-backoffice-ui/src/hooks/useSettings.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";
-import {
-  Codec,
-  buildCodecForObject,
-  codecForBoolean,
-  codecForConstString,
-  codecForEither,
-  codecForString,
-} from "@gnu-taler/taler-util";
-
-export interface Settings {
-  advanceOrderMode: boolean;
-  dateFormat: "ymd" | "dmy" | "mdy";
-}
-
-const defaultSettings: Settings = {
-  advanceOrderMode: false,
-  dateFormat: "ymd",
-}
-
-export const codecForSettings = (): Codec<Settings> =>
-  buildCodecForObject<Settings>()
-    .property("advanceOrderMode", codecForBoolean())
-    .property("dateFormat", codecForEither(
-      codecForConstString("ymd"),
-      codecForConstString("dmy"),
-      codecForConstString("mdy"),
-    ))
-    .build("Settings");
-
-const SETTINGS_KEY = buildStorageKey("merchant-settings", codecForSettings());
-
-export function useSettings(): [
-  Readonly<Settings>,
-  (s: Settings) => void,
-] {
-  const { value, update } = useLocalStorage(SETTINGS_KEY, defaultSettings);
-
-  // const parsed: Settings = value ?? defaultSettings;
-  // function updateField<T extends keyof Settings>(k: T, v: Settings[T]) {
-  //   const next = { ...parsed, [k]: v }
-  //   update(next);
-  // }
-  return [value, update];
-}
-
-export function dateFormatForSettings(s: Settings): string {
-  switch (s.dateFormat) {
-    case "ymd": return "yyyy/MM/dd"
-    case "dmy": return "dd/MM/yyyy"
-    case "mdy": return "MM/dd/yyyy"
-  }
-}
-
-export function datetimeFormatForSettings(s: Settings): string {
-  return dateFormatForSettings(s) + " HH:mm:ss"
-}
\ No newline at end of file
diff --git a/packages/merchant-backoffice-ui/src/hooks/webhooks.ts 
b/packages/merchant-backoffice-ui/src/hooks/webhooks.ts
index ad6bf96e2..994bfdbb0 100644
--- a/packages/merchant-backoffice-ui/src/hooks/webhooks.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/webhooks.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/index.html 
b/packages/merchant-backoffice-ui/src/index.html
index 3e027f056..aed14a1de 100644
--- a/packages/merchant-backoffice-ui/src/index.html
+++ b/packages/merchant-backoffice-ui/src/index.html
@@ -1,6 +1,6 @@
 <!--
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/index.tsx 
b/packages/merchant-backoffice-ui/src/index.tsx
index 87ed8e26f..46a3223bb 100644
--- a/packages/merchant-backoffice-ui/src/index.tsx
+++ b/packages/merchant-backoffice-ui/src/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -21,4 +21,8 @@ import "./scss/main.scss";
 
 const app = document.getElementById("app");
 
-render(<Application />, app as any);
+if (app) {
+  render(<Application />, app);
+} else {
+  console.error("HTML element with id 'app' not found.");
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/admin/create/Create.stories.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/create/Create.stories.tsx
index 93ada2374..ec54dc150 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/create/Create.stories.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/admin/create/Create.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx
index f95beba19..8ce7c1d3a 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/admin/create/InstanceCreatedSuccessfully.tsx
 
b/packages/merchant-backoffice-ui/src/paths/admin/create/InstanceCreatedSuccessfully.tsx
index c620c6482..939f9b06a 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/admin/create/InstanceCreatedSuccessfully.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/admin/create/InstanceCreatedSuccessfully.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/paths/admin/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/create/index.tsx
index 2de019276..cbda65bfe 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/create/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/admin/create/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/paths/admin/create/stories.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/create/stories.tsx
index 0161e9dc1..9a947c9d5 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/create/stories.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/admin/create/stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/paths/admin/index.stories.ts 
b/packages/merchant-backoffice-ui/src/paths/admin/index.stories.ts
index fdae1a24d..3c16c0e57 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/index.stories.ts
+++ b/packages/merchant-backoffice-ui/src/paths/admin/index.stories.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/admin/list/TableActive.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/list/TableActive.tsx
index 698768903..0011ae1a9 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/list/TableActive.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/admin/list/TableActive.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/admin/list/View.stories.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/list/View.stories.tsx
index e0f5d5430..c4c0996f6 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/list/View.stories.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/admin/list/View.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/paths/admin/list/View.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/list/View.tsx
index b59112338..35b59633b 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/list/View.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/admin/list/View.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx
index 2f839291b..d01460ac9 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/Create.stories.tsx
index 3336c53a4..50cd801d8 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/Create.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/Create.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx
index 8539e6783..bf16686f4 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx
index b458efe31..a2351964a 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/List.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/List.stories.tsx
index 6b4b63735..18e762642 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/List.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/List.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/ListPage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/ListPage.tsx
index 24da755b9..3359d1a95 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/ListPage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/ListPage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/Table.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/Table.tsx
index 95564208e..95e684b7b 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/Table.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx
index 04b6c51fd..51139c3f3 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/Update.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/Update.stories.tsx
index d6b1d65e0..06ea9d07a 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/Update.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/Update.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx
index 516015df7..6b67a79a4 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/index.tsx
index 44dee7651..ca0b692a3 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/details/DetailPage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/details/DetailPage.tsx
index 21dadb1e3..6e9b51106 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/details/DetailPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/details/DetailPage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/details/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/details/index.tsx
index 9b393b818..13dd3a2f6 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/details/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/details/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/details/stories.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/details/stories.tsx
index d7f61a8a5..aabe67e00 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/details/stories.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/details/stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/index.stories.ts 
b/packages/merchant-backoffice-ui/src/paths/instance/index.stories.ts
index 50918e131..8f06937df 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/index.stories.ts
+++ b/packages/merchant-backoffice-ui/src/paths/instance/index.stories.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.stories.tsx
index d33f64ada..a914639e5 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.tsx
index 338081886..2ec0137d9 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/index.tsx
index 5b93ac169..664f05f66 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
index bd9f65718..fc814b68f 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
index 62ceaa24b..5633d93ab 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -41,7 +41,7 @@ import { NonInventoryProductFrom } from 
"../../../../components/product/NonInven
 import { ProductList } from "../../../../components/product/ProductList.js";
 import { useConfigContext } from "../../../../context/config.js";
 import { MerchantBackend, WithId } from "../../../../declaration.js";
-import { useSettings } from "../../../../hooks/useSettings.js";
+import { usePreference } from "../../../../hooks/preference.js";
 import { OrderCreateSchema as schema } from "../../../../schemas/index.js";
 import { rate } from "../../../../utils/amount.js";
 import { undefinedIfEmpty } from "../../../../utils/table.js";
@@ -133,7 +133,7 @@ export function CreatePage({
   const instance_default = with_defaults(instanceConfig, config.currency)
   const [value, valueHandler] = useState(instance_default);
   const zero = Amounts.zeroOfCurrency(config.currency);
-  const [settings, updateSettings] = useSettings()
+  const [settings, updateSettings] = usePreference()
   const inventoryList = Object.values(value.inventoryProducts || {});
   const productList = Object.values(value.products || {});
 
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
index 88a984c97..3f7b20f52 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx
index 2474fd042..d2a8619ce 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Detail.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Detail.stories.tsx
index 8b892e122..63f0d5dc4 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Detail.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Detail.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
index 5ff76e37a..1efaaf6e0 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -20,7 +20,7 @@
  */
 
 import { AmountJson, Amounts, stringifyRefundUri } from 
"@gnu-taler/taler-util";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import { useMerchantApiContext, useTranslationContext } from 
"@gnu-taler/web-util/browser";
 import { format, formatDistance } from "date-fns";
 import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
@@ -33,9 +33,8 @@ import { InputGroup } from 
"../../../../components/form/InputGroup.js";
 import { InputLocation } from "../../../../components/form/InputLocation.js";
 import { TextField } from "../../../../components/form/TextField.js";
 import { ProductList } from "../../../../components/product/ProductList.js";
-import { useBackendContext } from "../../../../context/backend.js";
 import { MerchantBackend } from "../../../../declaration.js";
-import { datetimeFormatForSettings, useSettings } from 
"../../../../hooks/useSettings.js";
+import { datetimeFormatForSettings, usePreference } from 
"../../../../hooks/preference.js";
 import { mergeRefunds } from "../../../../utils/amount.js";
 import { RefundModal } from "../list/Table.js";
 import { Event, Timeline } from "./Timeline.js";
@@ -193,7 +192,7 @@ function ClaimedPage({
 
   const [value, valueHandler] = useState<Partial<Claimed>>(order);
   const { i18n } = useTranslationContext();
-  const [settings] = useSettings()
+  const [settings] = usePreference()
 
   return (
     <div>
@@ -416,9 +415,10 @@ function PaidPage({
   })
 
   const [value, valueHandler] = useState<Partial<Paid>>(order);
-  const { url: backendURL } = useBackendContext()
+  const { url: backendURL } = useMerchantApiContext();
+
   const refundurl = stringifyRefundUri({
-    merchantBaseUrl: backendURL,
+    merchantBaseUrl: backendURL.href,
     orderId: order.contract_terms.order_id
   })
   const refundable =
@@ -611,7 +611,7 @@ function UnpaidPage({
 }) {
   const [value, valueHandler] = useState<Partial<Unpaid>>(order);
   const { i18n } = useTranslationContext();
-  const [settings] = useSettings()
+  const [settings] = usePreference()
   return (
     <div>
       <section class="hero is-hero-bar">
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Timeline.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Timeline.tsx
index 8c863f386..2d62e2252 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Timeline.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Timeline.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -16,7 +16,7 @@
 import { format } from "date-fns";
 import { h } from "preact";
 import { useEffect, useState } from "preact/hooks";
-import { datetimeFormatForSettings, useSettings } from 
"../../../../hooks/useSettings.js";
+import { datetimeFormatForSettings, usePreference } from 
"../../../../hooks/preference.js";
 
 interface Props {
   events: Event[];
@@ -31,7 +31,7 @@ export function Timeline({ events: e }: Props) {
   });
 
   events.sort((a, b) => a.when.getTime() - b.when.getTime());
-  const [settings] = useSettings();
+  const [settings] = usePreference();
   const [state, setState] = useState(events);
   useEffect(() => {
     const handle = setTimeout(() => {
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx
index 1517a3c42..dfeaa4447 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/List.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/List.stories.tsx
index 156c577f4..9df006083 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/List.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/List.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
index 9f80719a1..b45d468cb 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -26,7 +26,7 @@ import { useState } from "preact/hooks";
 import { DatePicker } from "../../../../components/picker/DatePicker.js";
 import { MerchantBackend, WithId } from "../../../../declaration.js";
 import { CardTable } from "./Table.js";
-import { dateFormatForSettings, useSettings } from 
"../../../../hooks/useSettings.js";
+import { dateFormatForSettings, usePreference } from 
"../../../../hooks/preference.js";
 
 export interface ListPageProps {
   onShowAll: () => void;
@@ -85,7 +85,7 @@ export function ListPage({
   const { i18n } = useTranslationContext();
   const dateTooltip = i18n.str`select date to show nearby orders`;
   const [pickDate, setPickDate] = useState(false);
-  const [settings] = useSettings();
+  const [settings] = usePreference();
 
   return (
     <Fragment>
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx
index 2a8e65282..87e84945c 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -36,7 +36,7 @@ import { ConfirmModal } from 
"../../../../components/modal/index.js";
 import { useConfigContext } from "../../../../context/config.js";
 import { MerchantBackend, WithId } from "../../../../declaration.js";
 import { mergeRefunds } from "../../../../utils/amount.js";
-import { datetimeFormatForSettings, useSettings } from 
"../../../../hooks/useSettings.js";
+import { datetimeFormatForSettings, usePreference } from 
"../../../../hooks/preference.js";
 
 type Entity = MerchantBackend.Orders.OrderHistoryEntry & WithId;
 interface Props {
@@ -137,7 +137,7 @@ function Table({
   hasMoreBefore,
 }: TableProps): VNode {
   const { i18n } = useTranslationContext();
-  const [settings] = useSettings();
+  const [settings] = usePreference();
   return (
     <div class="table-container">
       {hasMoreBefore && (
@@ -260,7 +260,7 @@ export function RefundModal({
 }: RefundModalProps): VNode {
   type State = { mainReason?: string; description?: string; refund?: string };
   const [form, setValue] = useState<State>({});
-  const [settings] = useSettings();
+  const [settings] = usePreference();
   const { i18n } = useTranslationContext();
   // const [errors, setErrors] = useState<FormErrors<State>>({});
 
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx
index 92e714fb8..369ef8c8b 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/Create.stories.tsx
index 26f851cc8..36b31ebe8 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/Create.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/Create.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatePage.tsx
index b709b216c..83345de3e 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx
index a48b6fe63..c6591cdbe 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/index.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/index.tsx
index 648846793..f0b419f68 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/List.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/List.stories.tsx
index b18049674..49032c80e 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/List.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/List.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/ListPage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/ListPage.tsx
index 4efee9781..f3b5a2088 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/ListPage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/ListPage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/Table.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/Table.tsx
index 1f7114a85..94091e1a7 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/Table.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/Table.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/index.tsx
index 2aae8738a..a3299326c 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/Update.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/Update.stories.tsx
index d6b1d65e0..06ea9d07a 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/Update.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/Update.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/UpdatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/UpdatePage.tsx
index 85bb272aa..310810576 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/UpdatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/UpdatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/index.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/index.tsx
index 7c7092a4e..922a94364 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/Create.stories.tsx
index 2fc0819bb..22bbfe28a 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/Create.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/Create.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatePage.tsx
index becaf8f3a..6cbc26d8d 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatedSuccessfully.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatedSuccessfully.tsx
index 6b02430cc..2b6ebed45 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatedSuccessfully.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatedSuccessfully.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/index.tsx
index 775690bd1..5b1b5ecfe 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/list/List.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/list/List.stories.tsx
index c2c4d548c..a2f996221 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/products/list/List.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/list/List.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
index 805517ae8..2526e4d33 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -32,7 +32,7 @@ import {
 import { InputCurrency } from "../../../../components/form/InputCurrency.js";
 import { InputNumber } from "../../../../components/form/InputNumber.js";
 import { MerchantBackend, WithId } from "../../../../declaration.js";
-import { dateFormatForSettings, useSettings } from 
"../../../../hooks/useSettings.js";
+import { dateFormatForSettings, usePreference } from 
"../../../../hooks/preference.js";
 
 type Entity = MerchantBackend.Products.ProductDetail & WithId;
 
@@ -123,7 +123,7 @@ function Table({
   onDelete,
 }: TableProps): VNode {
   const { i18n } = useTranslationContext();
-  const [settings] = useSettings();
+  const [settings] = usePreference();
   return (
     <div class="table-container">
       <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
index 34b21daa2..6adc221da 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/update/Update.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/Update.stories.tsx
index a85b13b8b..d1dc9d540 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/products/update/Update.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/Update.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/update/UpdatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/UpdatePage.tsx
index 97715171e..53aa9d61f 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/products/update/UpdatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/UpdatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx
index 8e0f7647f..2d3e7bd6b 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/Create.stories.tsx
index c9d17ea3b..53025f153 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/Create.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/Create.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx
index a2c0c9dfb..d27f6a022 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/index.tsx
index a29ee53b6..f76146812 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/List.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/List.stories.tsx
index 702e9ba4a..707324d40 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/List.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/List.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/ListPage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/ListPage.tsx
index bf6062c34..c21f64776 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/ListPage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/ListPage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/Table.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/Table.tsx
index 0de4fc86e..00d7982aa 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/Table.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/Table.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/index.tsx
index adb0833c4..78f744b39 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/Qr.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/Qr.stories.tsx
index eb853c8ff..c0059c7bc 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/Qr.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/Qr.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/QrPage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/QrPage.tsx
index 5140aae3a..809151565 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/QrPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/QrPage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx
index 7db7478f7..65ccc2dcc 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/Update.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/Update.stories.tsx
index 8d07cb31f..303d17b72 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/Update.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/Update.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx
index cfb521c73..cdf2ebab4 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx
index fb9b1d8aa..1975ed479 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/use/Use.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/use/Use.stories.tsx
index 13576d94d..d91888b97 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/use/Use.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/use/Use.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/use/UsePage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/use/UsePage.tsx
index 983804d3e..93f303537 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/use/UsePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/use/UsePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/templates/use/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/templates/use/index.tsx
index ed1242ef5..441a5c5e0 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/use/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/use/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx
index 549e7581f..1e9186624 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx
index 22365c9e1..13642ec22 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/token/stories.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/token/stories.tsx
index 5f0f56f2d..581828657 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/token/stories.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/token/stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/Create.stories.tsx
index 64b67335c..ca38defc3 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/Create.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/Create.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/CreatePage.tsx
index 13f5f3c12..eb25045a0 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/CreatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx
index 25551a031..77a8c65fb 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/List.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/List.stories.tsx
index 92b3f9853..ba22cb7d5 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/List.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/List.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
index 02b12c4c2..794d37fe6 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx
index b7adcc248..3792db9b0 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -24,7 +24,7 @@ import { format } from "date-fns";
 import { h, VNode } from "preact";
 import { StateUpdater, useState } from "preact/hooks";
 import { MerchantBackend, WithId } from "../../../../declaration.js";
-import { datetimeFormatForSettings, useSettings } from 
"../../../../hooks/useSettings.js";
+import { datetimeFormatForSettings, usePreference } from 
"../../../../hooks/preference.js";
 
 type Entity = MerchantBackend.Transfers.TransferDetails & WithId;
 
@@ -122,7 +122,7 @@ function Table({
   hasMoreBefore,
 }: TableProps): VNode {
   const { i18n } = useTranslationContext();
-  const [settings] = useSettings();
+  const [settings] = usePreference();
   return (
     <div class="table-container">
       {hasMoreBefore && (
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx
index 0fdbb9bc3..1402df4c1 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/update/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/update/index.tsx
index 84cc95e72..719f99209 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/update/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/update/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/update/Update.stories.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/update/Update.stories.tsx
index 817a7025c..2accb7685 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/update/Update.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/update/Update.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
index a27a0cb06..ff0d55d2d 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
index e44cf5c0f..be3793ac3 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/Create.stories.tsx
index 4857ede97..2e2a58b33 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/Create.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/Create.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/CreatePage.tsx
index bfa2a883e..b89e5e6bf 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/CreatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/index.tsx
index 924e6d9b8..e1b8aa88e 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/create/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/List.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/List.stories.tsx
index 702e9ba4a..707324d40 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/List.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/List.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/ListPage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/ListPage.tsx
index 87e221e3c..be7c575a0 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/ListPage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/ListPage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/Table.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/Table.tsx
index cca755813..debbd850b 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/Table.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/index.tsx
index a6f6f1511..c4b773669 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/Update.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/Update.stories.tsx
index 8d07cb31f..303d17b72 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/Update.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/Update.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/UpdatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/UpdatePage.tsx
index 76a23b6e5..304ac90f3 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/UpdatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/UpdatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/index.tsx
index 3f723ed87..12374d82a 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/paths/login/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/login/index.tsx
index 6c33dd06e..d155dd255 100644
--- a/packages/merchant-backoffice-ui/src/paths/login/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/login/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -19,198 +19,221 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { ComponentChildren, Fragment, h, VNode } from "preact";
-import { useCallback, useEffect, useState } from "preact/hooks";
-import { useBackendContext } from "../../context/backend.js";
-import { useInstanceContext } from "../../context/instance.js";
-import { AccessToken, LoginToken } from "../../declaration.js";
-import { useCredentialsChecker } from "../../hooks/backend.js";
+import {
+  useMerchantApiContext,
+  useTranslationContext,
+} from "@gnu-taler/web-util/browser";
+import { ComponentChildren, Fragment, VNode, h } from "preact";
+import { useState } from "preact/hooks";
 import { NotificationCard } from "../../components/menu/index.js";
+import { AccessToken } from "../../declaration.js";
+import { useSessionState } from "../../hooks/session.js";
 import { Notification } from "../../utils/types.js";
+import { HttpStatusCode } from "@gnu-taler/taler-util";
 
 interface Props {
-  onConfirm: (token: LoginToken | undefined) => void;
 }
 
 function normalizeToken(r: string): AccessToken {
   return `secret-token:${r}` as AccessToken;
 }
 
-export function LoginPage({ onConfirm }: Props): VNode {
-  const { url: backendURL } = useBackendContext();
-  const { admin, id } = useInstanceContext();
-  const { requestNewLoginToken } = useCredentialsChecker();
+export function LoginPage(_p: Props): VNode {
   const [token, setToken] = useState("");
   const [notif, setNotif] = useState<Notification | undefined>(undefined);
-
+  const { logIn } = useSessionState();
+  const { lib } = useMerchantApiContext();
 
   const { i18n } = useTranslationContext();
 
-
-  const doLogin = useCallback(async function doLoginImpl() {
+  async function doLoginImpl() {
     const secretToken = normalizeToken(token);
-    const baseUrl = id === undefined ? backendURL : 
`${backendURL}/instances/${id}`
-    const result = await requestNewLoginToken(baseUrl, secretToken);
-    if (result.valid) {
-      const { token, expiration } = result
-      onConfirm({ token, expiration });
+    const result = await lib.authenticate.createAccessToken(secretToken, {
+      scope: "write",
+      duration: {
+        d_us: "forever"
+      },
+      refreshable: true,
+    });
+    if (result.type === "ok") {
+      const { access_token } = result.body;
+      logIn({ token: access_token });
+      return;
     } else {
-      onConfirm(undefined);
-      setNotif({
-        message: "Your password is incorrect",
-        type: "ERROR",
-      });
+      switch(result.case) {
+        case HttpStatusCode.Unauthorized: {
+          setNotif({
+            message: "Your password is incorrect",
+            type: "ERROR",
+          });
+          return;
+        }
+        case HttpStatusCode.NotFound: {
+          setNotif({
+            message: "Your instance not found",
+            type: "ERROR",
+          });
+          return;
+        }
+      }
     }
-  }, [id, token])
+  }
 
   if (admin && id !== "default") {
     //admin trying to access another instance
-    return (<div class="columns is-centered" style={{ margin: "auto" }}>
-      <div class="column is-two-thirds ">
-        <div class="modal-card" style={{ width: "100%", margin: 0 }}>
-          <header
-            class="modal-card-head"
-            style={{ border: "1px solid", borderBottom: 0 }}
-          >
-            <p class="modal-card-title">{i18n.str`Login required`}</p>
-          </header>
-          <section
-            class="modal-card-body"
-            style={{ border: "1px solid", borderTop: 0, borderBottom: 0 }}
-          >
-
-            <p>
-              <i18n.Translate>Need the access token for the 
instance.</i18n.Translate>
-            </p>
-            <div class="field is-horizontal">
-              <div class="field-label is-normal">
-                <label class="label">
-                  <i18n.Translate>Access Token</i18n.Translate>
-                </label>
-              </div>
-              <div class="field-body">
-                <div class="field">
-                  <p class="control is-expanded">
-                    <input
-                      class="input"
-                      type="password"
-                      placeholder={"current access token"}
-                      name="token"
-                      onKeyPress={(e) =>
-                        e.keyCode === 13
-                          ? doLogin()
-                          : null
-                      }
-                      value={token}
-                      onInput={(e): void => setToken(e?.currentTarget.value)}
-                    />
-                  </p>
+    return (
+      <div class="columns is-centered" style={{ margin: "auto" }}>
+        <div class="column is-two-thirds ">
+          <div class="modal-card" style={{ width: "100%", margin: 0 }}>
+            <header
+              class="modal-card-head"
+              style={{ border: "1px solid", borderBottom: 0 }}
+            >
+              <p class="modal-card-title">{i18n.str`Login required`}</p>
+            </header>
+            <section
+              class="modal-card-body"
+              style={{ border: "1px solid", borderTop: 0, borderBottom: 0 }}
+            >
+              <p>
+                <i18n.Translate>
+                  Need the access token for the instance.
+                </i18n.Translate>
+              </p>
+              <div class="field is-horizontal">
+                <div class="field-label is-normal">
+                  <label class="label">
+                    <i18n.Translate>Access Token</i18n.Translate>
+                  </label>
+                </div>
+                <div class="field-body">
+                  <div class="field">
+                    <p class="control is-expanded">
+                      <input
+                        class="input"
+                        type="password"
+                        placeholder={"current access token"}
+                        name="token"
+                        onKeyPress={(e) =>
+                          e.keyCode === 13 ? doLoginImpl() : null
+                        }
+                        value={token}
+                        onInput={(e): void => setToken(e?.currentTarget.value)}
+                      />
+                    </p>
+                  </div>
                 </div>
               </div>
-            </div>
-          </section>
-          <footer
-            class="modal-card-foot "
-            style={{
-              justifyContent: "flex-end",
-              border: "1px solid",
-              borderTop: 0,
-            }}
-          >
-            <AsyncButton
-              onClick={doLogin}
+            </section>
+            <footer
+              class="modal-card-foot "
+              style={{
+                justifyContent: "flex-end",
+                border: "1px solid",
+                borderTop: 0,
+              }}
             >
-              <i18n.Translate>Confirm</i18n.Translate>
-            </AsyncButton>
-          </footer>
+              <AsyncButton onClick={doLoginImpl}>
+                <i18n.Translate>Confirm</i18n.Translate>
+              </AsyncButton>
+            </footer>
+          </div>
         </div>
       </div>
-    </div>)
+    );
   }
 
-  return (<Fragment>
-    <NotificationCard notification={notif} />
-    <div class="columns is-centered" style={{ margin: "auto" }}>
-      <div class="column is-two-thirds ">
-        <div class="modal-card" style={{ width: "100%", margin: 0 }}>
-          <header
-            class="modal-card-head"
-            style={{ border: "1px solid", borderBottom: 0 }}
-          >
-            <p class="modal-card-title">{i18n.str`Login required`}</p>
-          </header>
-          <section
-            class="modal-card-body"
-            style={{ border: "1px solid", borderTop: 0, borderBottom: 0 }}
-          >
-            <i18n.Translate>Please enter your access token.</i18n.Translate>
-
-            <div class="field is-horizontal">
-              <div class="field-label is-normal">
-                <label class="label">
-                  <i18n.Translate>Access Token</i18n.Translate>
-                </label>
-              </div>
-              <div class="field-body">
+  return (
+    <Fragment>
+      <NotificationCard notification={notif} />
+      <div class="columns is-centered" style={{ margin: "auto" }}>
+        <div class="column is-two-thirds ">
+          <div class="modal-card" style={{ width: "100%", margin: 0 }}>
+            <header
+              class="modal-card-head"
+              style={{ border: "1px solid", borderBottom: 0 }}
+            >
+              <p class="modal-card-title">{i18n.str`Login required`}</p>
+            </header>
+            <section
+              class="modal-card-body"
+              style={{ border: "1px solid", borderTop: 0, borderBottom: 0 }}
+            >
+              <i18n.Translate>Please enter your access token.</i18n.Translate>
 
-                <div class="field">
-                  <p class="control is-expanded">
-                    <input
-                      class="input"
-                      type="password"
-                      placeholder={"current access token"}
-                      name="token"
-                      onKeyPress={(e) =>
-                        e.keyCode === 13
-                          ? doLogin()
-                          : null
-                      }
-                      value={token}
-                      onInput={(e): void => setToken(e?.currentTarget.value)}
-                    />
-                  </p>
+              <div class="field is-horizontal">
+                <div class="field-label is-normal">
+                  <label class="label">
+                    <i18n.Translate>Access Token</i18n.Translate>
+                  </label>
+                </div>
+                <div class="field-body">
+                  <div class="field">
+                    <p class="control is-expanded">
+                      <input
+                        class="input"
+                        type="password"
+                        placeholder={"current access token"}
+                        name="token"
+                        onKeyPress={(e) =>
+                          e.keyCode === 13 ? doLoginImpl() : null
+                        }
+                        value={token}
+                        onInput={(e): void => setToken(e?.currentTarget.value)}
+                      />
+                    </p>
+                  </div>
                 </div>
               </div>
-            </div>
-          </section>
-          <footer
-            class="modal-card-foot "
-            style={{
-              justifyContent: "space-between",
-              border: "1px solid",
-              borderTop: 0,
-            }}
-          >
-            <div />
-            <AsyncButton
-              type="is-info"
-              onClick={doLogin}
+            </section>
+            <footer
+              class="modal-card-foot "
+              style={{
+                justifyContent: "space-between",
+                border: "1px solid",
+                borderTop: 0,
+              }}
             >
-              <i18n.Translate>Confirm</i18n.Translate>
-            </AsyncButton>
-
-          </footer>
+              <div />
+              <AsyncButton type="is-info" onClick={doLoginImpl}>
+                <i18n.Translate>Confirm</i18n.Translate>
+              </AsyncButton>
+            </footer>
+          </div>
         </div>
       </div>
-    </div>
-  </Fragment>
-
+    </Fragment>
   );
 }
 
-function AsyncButton({ onClick, disabled, type = "", children }: { type?: 
string, disabled?: boolean, onClick: () => Promise<void>, children: 
ComponentChildren }): VNode {
-  const [running, setRunning] = useState(false)
-  return <button class={"button " + type} disabled={disabled || running} 
onClick={() => {
-    setRunning(true)
-    onClick().then(() => {
-      setRunning(false)
-    }).catch(() => {
-      setRunning(false)
-    })
-  }}>
-    {children}
-  </button>
+function AsyncButton({
+  onClick,
+  disabled,
+  type = "",
+  children,
+}: {
+  type?: string;
+  disabled?: boolean;
+  onClick: () => Promise<void>;
+  children: ComponentChildren;
+}): VNode {
+  const [running, setRunning] = useState(false);
+  return (
+    <button
+      class={"button " + type}
+      disabled={disabled || running}
+      onClick={() => {
+        setRunning(true);
+        onClick()
+          .then(() => {
+            setRunning(false);
+          })
+          .catch(() => {
+            setRunning(false);
+          });
+      }}
+    >
+      {children}
+    </button>
+  );
 }
-
-
diff --git a/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
index 061a67025..68adb79bf 100644
--- a/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/paths/settings/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/settings/index.tsx
index 8e69537ec..4efda43be 100644
--- a/packages/merchant-backoffice-ui/src/paths/settings/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/settings/index.tsx
@@ -4,7 +4,7 @@ import { FormErrors, FormProvider } from 
"../../components/form/FormProvider.js"
 import { InputSelector } from "../../components/form/InputSelector.js";
 import { InputToggle } from "../../components/form/InputToggle.js";
 import { LangSelector } from "../../components/menu/LangSelector.js";
-import { Settings, useSettings } from "../../hooks/useSettings.js";
+import { Settings, usePreference } from "../../hooks/preference.js";
 
 function getBrowserLang(): string | undefined {
   if (typeof window === "undefined") return undefined;
@@ -18,7 +18,7 @@ export function Settings({ onClose }: { onClose?: () => void 
}): VNode {
   const borwserLang = getBrowserLang()
   const { update } = useLang(undefined, {})
 
-  const [value, updateValue] = useSettings()
+  const [value, updateValue] = usePreference()
   const errors: FormErrors<Settings> = {
   }
 
diff --git a/packages/merchant-backoffice-ui/src/schemas/index.ts 
b/packages/merchant-backoffice-ui/src/schemas/index.ts
index 5d168d6ac..dc4517e16 100644
--- a/packages/merchant-backoffice-ui/src/schemas/index.ts
+++ b/packages/merchant-backoffice-ui/src/schemas/index.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_aside.scss 
b/packages/merchant-backoffice-ui/src/scss/_aside.scss
index e0922093b..b7b59516b 100644
--- a/packages/merchant-backoffice-ui/src/scss/_aside.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_aside.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_card.scss 
b/packages/merchant-backoffice-ui/src/scss/_card.scss
index 62db7f457..a4118400f 100644
--- a/packages/merchant-backoffice-ui/src/scss/_card.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_card.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_custom-calendar.scss 
b/packages/merchant-backoffice-ui/src/scss/_custom-calendar.scss
index 34c40092b..62414a00a 100644
--- a/packages/merchant-backoffice-ui/src/scss/_custom-calendar.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_custom-calendar.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_footer.scss 
b/packages/merchant-backoffice-ui/src/scss/_footer.scss
index 5855af742..7e90c40cc 100644
--- a/packages/merchant-backoffice-ui/src/scss/_footer.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_footer.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_form.scss 
b/packages/merchant-backoffice-ui/src/scss/_form.scss
index bd28a17cf..126d3d0cc 100644
--- a/packages/merchant-backoffice-ui/src/scss/_form.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_form.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_hero-bar.scss 
b/packages/merchant-backoffice-ui/src/scss/_hero-bar.scss
index 0276468d7..cb3f438e9 100644
--- a/packages/merchant-backoffice-ui/src/scss/_hero-bar.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_hero-bar.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_loading.scss 
b/packages/merchant-backoffice-ui/src/scss/_loading.scss
index d88d8c355..32f64f276 100644
--- a/packages/merchant-backoffice-ui/src/scss/_loading.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_loading.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_main-section.scss 
b/packages/merchant-backoffice-ui/src/scss/_main-section.scss
index 5a8b20ba0..444af5235 100644
--- a/packages/merchant-backoffice-ui/src/scss/_main-section.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_main-section.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_misc.scss 
b/packages/merchant-backoffice-ui/src/scss/_misc.scss
index 045d087e2..a0dbc64fc 100644
--- a/packages/merchant-backoffice-ui/src/scss/_misc.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_misc.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_modal.scss 
b/packages/merchant-backoffice-ui/src/scss/_modal.scss
index b2bfd3e9e..d2565e7c7 100644
--- a/packages/merchant-backoffice-ui/src/scss/_modal.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_modal.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_nav-bar.scss 
b/packages/merchant-backoffice-ui/src/scss/_nav-bar.scss
index 406e0392f..4c0e2f5cc 100644
--- a/packages/merchant-backoffice-ui/src/scss/_nav-bar.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_nav-bar.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_table.scss 
b/packages/merchant-backoffice-ui/src/scss/_table.scss
index e4fbfc7b3..6c7765a74 100644
--- a/packages/merchant-backoffice-ui/src/scss/_table.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_table.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_theme-default.scss 
b/packages/merchant-backoffice-ui/src/scss/_theme-default.scss
index e74ece0e9..f34497bde 100644
--- a/packages/merchant-backoffice-ui/src/scss/_theme-default.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_theme-default.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_tiles.scss 
b/packages/merchant-backoffice-ui/src/scss/_tiles.scss
index 94dd6c21d..75bc6b94e 100644
--- a/packages/merchant-backoffice-ui/src/scss/_tiles.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_tiles.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/_title-bar.scss 
b/packages/merchant-backoffice-ui/src/scss/_title-bar.scss
index bac3f6b42..5de384a32 100644
--- a/packages/merchant-backoffice-ui/src/scss/_title-bar.scss
+++ b/packages/merchant-backoffice-ui/src/scss/_title-bar.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/fonts/nunito.css 
b/packages/merchant-backoffice-ui/src/scss/fonts/nunito.css
index a578506e8..591fc3da2 100644
--- a/packages/merchant-backoffice-ui/src/scss/fonts/nunito.css
+++ b/packages/merchant-backoffice-ui/src/scss/fonts/nunito.css
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/libs/_all.scss 
b/packages/merchant-backoffice-ui/src/scss/libs/_all.scss
index cba6f26eb..ab8030a13 100644
--- a/packages/merchant-backoffice-ui/src/scss/libs/_all.scss
+++ b/packages/merchant-backoffice-ui/src/scss/libs/_all.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/scss/main.scss 
b/packages/merchant-backoffice-ui/src/scss/main.scss
index c4be8aa73..4a46472f9 100644
--- a/packages/merchant-backoffice-ui/src/scss/main.scss
+++ b/packages/merchant-backoffice-ui/src/scss/main.scss
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/bank-ui/src/settings.ts 
b/packages/merchant-backoffice-ui/src/settings.ts
similarity index 51%
copy from packages/bank-ui/src/settings.ts
copy to packages/merchant-backoffice-ui/src/settings.ts
index c7c56d299..0e377bec2 100644
--- a/packages/bank-ui/src/settings.ts
+++ b/packages/merchant-backoffice-ui/src/settings.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2022-2024 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -17,57 +17,28 @@
 import {
   Codec,
   buildCodecForObject,
-  codecForBoolean,
-  codecForMap,
+  canonicalizeBaseUrl,
   codecForString,
-  codecOptional,
+  codecOptional
 } from "@gnu-taler/taler-util";
 
-export interface BankUiSettings {
-  // Where libeufin backend is localted
+export interface MerchantUiSettings {
+  // Where merchant backend is localted
   // default: window.origin without "webui/"
   backendBaseURL?: string;
-  // Shows a button "create random account" in the registration form
-  // Useful for testing
-  // default: false
-  allowRandomAccountCreation?: boolean;
-  // Create all random accounts with password "123"
-  // Useful for testing
-  // default: false
-  simplePasswordForRandomAccounts?: boolean;
-  // URL where the user is going to be redirected after
-  // clicking in Taler Logo
-  // default: home page
-  iconLinkURL?: string;
-  // Mapping for every link shown in the top navitation bar
-  //  - key: link label, what the user will read
-  //  - value: link target, where the user is going to be redirected
-  // default: empty list
-  topNavSites?: Record<string, string>;
 }
 
 /**
  * Global settings for the bank UI.
  */
-const defaultSettings: BankUiSettings = {
+const defaultSettings: MerchantUiSettings = {
   backendBaseURL: buildDefaultBackendBaseURL(),
-  iconLinkURL: undefined,
-  simplePasswordForRandomAccounts: false,
-  allowRandomAccountCreation: false,
-  topNavSites: {},
 };
 
-const codecForBankUISettings = (): Codec<BankUiSettings> =>
-  buildCodecForObject<BankUiSettings>()
+const codecForBankUISettings = (): Codec<MerchantUiSettings> =>
+  buildCodecForObject<MerchantUiSettings>()
     .property("backendBaseURL", codecOptional(codecForString()))
-    .property("allowRandomAccountCreation", codecOptional(codecForBoolean()))
-    .property(
-      "simplePasswordForRandomAccounts",
-      codecOptional(codecForBoolean()),
-    )
-    .property("iconLinkURL", codecOptional(codecForString()))
-    .property("topNavSites", codecOptional(codecForMap(codecForString())))
-    .build("BankUiSettings");
+    .build("MerchantUiSettings");
 
 function removeUndefineField<T extends object>(obj: T): T {
   const keys = Object.keys(obj) as Array<keyof T>;
@@ -79,7 +50,7 @@ function removeUndefineField<T extends object>(obj: T): T {
   }, obj);
 }
 
-export function fetchSettings(listener: (s: BankUiSettings) => void): void {
+export function fetchSettings(listener: (s: MerchantUiSettings) => void): void 
{
   fetch("./settings.json")
     .then((resp) => resp.json())
     .then((json) => codecForBankUISettings().decode(json))
@@ -95,13 +66,19 @@ export function fetchSettings(listener: (s: BankUiSettings) 
=> void): void {
     });
 }
 
-function buildDefaultBackendBaseURL(): string | undefined {
+export function buildDefaultBackendBaseURL(): string {
   if (typeof window !== "undefined") {
     const currentLocation = new URL(
       window.location.pathname,
       window.location.origin,
     ).href;
-    return currentLocation.replace("/webui", "");
+    /**
+     * By default, merchant backend serves the html content
+     * from the /webui root. This should cover most of the 
+     * cases and the rootPath will be the merchant backend
+     * URL where the instances are
+     */
+    return canonicalizeBaseUrl(currentLocation.replace("/webui", ""));
   }
-  return undefined;
+  throw Error("No default URL")
 }
diff --git a/packages/merchant-backoffice-ui/src/stories.test.ts 
b/packages/merchant-backoffice-ui/src/stories.test.ts
index abd993550..6ce88b916 100644
--- a/packages/merchant-backoffice-ui/src/stories.test.ts
+++ b/packages/merchant-backoffice-ui/src/stories.test.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/stories.tsx 
b/packages/merchant-backoffice-ui/src/stories.tsx
index 67e658016..8bb06b8cb 100644
--- a/packages/merchant-backoffice-ui/src/stories.tsx
+++ b/packages/merchant-backoffice-ui/src/stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/sw.js 
b/packages/merchant-backoffice-ui/src/sw.js
index 0b1799e23..bf52db6fa 100644
--- a/packages/merchant-backoffice-ui/src/sw.js
+++ b/packages/merchant-backoffice-ui/src/sw.js
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/utils/amount.ts 
b/packages/merchant-backoffice-ui/src/utils/amount.ts
index 475489d3e..fda997619 100644
--- a/packages/merchant-backoffice-ui/src/utils/amount.ts
+++ b/packages/merchant-backoffice-ui/src/utils/amount.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/utils/constants.ts 
b/packages/merchant-backoffice-ui/src/utils/constants.ts
index 7c4e288b3..9e7a69ed0 100644
--- a/packages/merchant-backoffice-ui/src/utils/constants.ts
+++ b/packages/merchant-backoffice-ui/src/utils/constants.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
@@ -27,8 +27,6 @@ export const PAYTO_WIRE_METHOD_LOOKUP =
 
 export const AMOUNT_REGEX = /^[a-zA-Z][a-zA-Z]{1,11}:[0-9][0-9,]*\.?[0-9,]*$/;
 
-export const INSTANCE_ID_LOOKUP = /\/instances\/([^/]*)\/?$/;
-
 export const AMOUNT_ZERO_REGEX = /^[a-zA-Z][a-zA-Z]*:0$/;
 
 export const CROCKFORD_BASE32_REGEX =
diff --git a/packages/merchant-backoffice-ui/src/utils/regex.test.ts 
b/packages/merchant-backoffice-ui/src/utils/regex.test.ts
index 984f1a472..78f2ef5ae 100644
--- a/packages/merchant-backoffice-ui/src/utils/regex.test.ts
+++ b/packages/merchant-backoffice-ui/src/utils/regex.test.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/utils/table.ts 
b/packages/merchant-backoffice-ui/src/utils/table.ts
index db2b2021c..306328aa1 100644
--- a/packages/merchant-backoffice-ui/src/utils/table.ts
+++ b/packages/merchant-backoffice-ui/src/utils/table.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/merchant-backoffice-ui/src/utils/types.ts 
b/packages/merchant-backoffice-ui/src/utils/types.ts
index 0d249f3c4..f96606a16 100644
--- a/packages/merchant-backoffice-ui/src/utils/types.ts
+++ b/packages/merchant-backoffice-ui/src/utils/types.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 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
diff --git a/packages/taler-util/src/http-client/bank-core.ts 
b/packages/taler-util/src/http-client/bank-core.ts
index c02bf1ec9..b544d56fe 100644
--- a/packages/taler-util/src/http-client/bank-core.ts
+++ b/packages/taler-util/src/http-client/bank-core.ts
@@ -76,7 +76,7 @@ export type TalerCoreBankErrorsByMethod<
 > = FailCasesByMethod<TalerCoreBankHttpClient, prop>;
 
 export enum TalerCoreBankCacheEviction {
-  DELELE_ACCOUNT,
+  DELETE_ACCOUNT,
   CREATE_ACCOUNT,
   UPDATE_ACCOUNT,
   UPDATE_PASSWORD,
diff --git a/packages/taler-util/src/http-client/merchant.ts 
b/packages/taler-util/src/http-client/merchant.ts
index 886844dba..7407cce66 100644
--- a/packages/taler-util/src/http-client/merchant.ts
+++ b/packages/taler-util/src/http-client/merchant.ts
@@ -67,9 +67,12 @@ import {
   nullEvictor,
 } from "./utils.js";
 
-export enum TalerMerchantCacheEviction {
+export enum TalerMerchantInstanceCacheEviction {
   CREATE_ORDER,
 }
+export enum TalerMerchantManagementCacheEviction {
+  CREATE_INSTANCE,
+}
 /**
  * Protocol version spoken with the core bank.
  *
@@ -83,12 +86,12 @@ export class TalerMerchantInstanceHttpClient {
   public readonly PROTOCOL_VERSION = "10:0:6";
 
   readonly httpLib: HttpRequestLibrary;
-  readonly cacheEvictor: CacheEvictor<TalerMerchantCacheEviction>;
+  readonly cacheEvictor: CacheEvictor<TalerMerchantInstanceCacheEviction>;
 
   constructor(
     readonly baseUrl: string,
     httpClient?: HttpRequestLibrary,
-    cacheEvictor?: CacheEvictor<TalerMerchantCacheEviction>,
+    cacheEvictor?: CacheEvictor<TalerMerchantInstanceCacheEviction>,
   ) {
     this.httpLib = httpClient ?? createPlatformHttpLib();
     this.cacheEvictor = cacheEvictor ?? nullEvictor;
@@ -353,16 +356,6 @@ export class TalerMerchantInstanceHttpClient {
     }
   }
 
-  /**
-   * Get the auth api against the current instance
-   *
-   * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-token
-   * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-token
-   */
-  getAuthenticationAPI(): URL {
-    return new URL(`/`, this.baseUrl);
-  }
-
   /**
    * 
https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private
    */
@@ -731,13 +724,15 @@ export class TalerMerchantInstanceHttpClient {
       method: "POST",
       body,
     });
-    return TalerMerchantInstanceHttpClient.procesOrderCreationResponse(resp);
+    return this.procesOrderCreationResponse(resp)
   }
 
-  private static async procesOrderCreationResponse(resp: HttpResponse) {
+  private async procesOrderCreationResponse(resp: HttpResponse) {
     switch (resp.status) {
-      case HttpStatusCode.Ok:
-        return opSuccessFromHttp(resp, codecForPostOrderResponse());
+      case HttpStatusCode.Ok: {
+        
this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_ORDER)
+        return opSuccessFromHttp(resp, codecForPostOrderResponse())
+      }
       case HttpStatusCode.NotFound:
         return opKnownHttpFailure(resp.status, resp);
       case HttpStatusCode.Conflict:
@@ -1257,7 +1252,7 @@ export class TalerMerchantInstanceHttpClient {
       body,
     });
 
-    return TalerMerchantInstanceHttpClient.procesOrderCreationResponse(resp);
+    return this.procesOrderCreationResponse(resp)
   }
 
   //
@@ -1475,18 +1470,32 @@ export class TalerMerchantInstanceHttpClient {
         return opUnknownFailure(resp, await resp.text());
     }
   }
+
+  /**
+   * Get the auth api against the current instance
+   *
+   * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-token
+   * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-token
+   */
+  getAuthenticationAPI(): URL {
+    return new URL(`private/`, this.baseUrl);
+  }
+
 }
 
 export class TalerMerchantManagementHttpClient extends 
TalerMerchantInstanceHttpClient {
+  readonly cacheManagementEvictor: 
CacheEvictor<TalerMerchantManagementCacheEviction>;
   constructor(
     readonly baseUrl: string,
     httpClient?: HttpRequestLibrary,
-    cacheEvictor?: CacheEvictor<TalerMerchantCacheEviction>,
+    cacheManagementEvictor?: 
CacheEvictor<TalerMerchantManagementCacheEviction>,
+    cacheEvictor?: CacheEvictor<TalerMerchantInstanceCacheEviction>,
   ) {
     super(baseUrl, httpClient, cacheEvictor);
+    this.cacheManagementEvictor = cacheManagementEvictor ?? nullEvictor;
   }
 
-  getSubInstanceApi(instanceId: string) {
+  getSubInstanceAPI(instanceId: string) {
     return new URL(`instances/${instanceId}`, this.baseUrl);
   }
 
@@ -1505,9 +1514,12 @@ export class TalerMerchantManagementHttpClient extends 
TalerMerchantInstanceHttp
       body,
     });
 
+
     switch (resp.status) {
-      case HttpStatusCode.NoContent:
+      case HttpStatusCode.NoContent: {
+        
this.cacheManagementEvictor.notifySuccess(TalerMerchantManagementCacheEviction.CREATE_INSTANCE)
         return opEmptySuccess(resp);
+      }
       case HttpStatusCode.Conflict:
         return opKnownHttpFailure(resp.status, resp);
       default:
diff --git a/packages/taler-util/src/index.ts b/packages/taler-util/src/index.ts
index 6b9a4ae2f..9bd4834d2 100644
--- a/packages/taler-util/src/index.ts
+++ b/packages/taler-util/src/index.ts
@@ -21,6 +21,7 @@ export * from "./helpers.js";
 export * from "./http-client/bank-conversion.js";
 export * from "./http-client/authentication.js";
 export * from "./http-client/bank-core.js";
+export * from "./http-client/merchant.js";
 export * from "./http-client/bank-integration.js";
 export * from "./http-client/bank-revenue.js";
 export * from "./http-client/bank-wire.js";
diff --git a/packages/web-util/src/context/activity.ts 
b/packages/web-util/src/context/activity.ts
new file mode 100644
index 000000000..570729471
--- /dev/null
+++ b/packages/web-util/src/context/activity.ts
@@ -0,0 +1,65 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022-2024 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/>
+ */
+
+import { ObservabilityEvent, TalerAuthenticationHttpClient, 
TalerBankConversionHttpClient, TalerCoreBankHttpClient, 
TalerMerchantInstanceHttpClient, TalerMerchantManagementHttpClient } from 
"@gnu-taler/taler-util";
+
+type Listener<Event> = (e: Event) => void;
+type Unsuscriber = () => void;
+export type Suscriber<Event> = (fn: Listener<Event>) => Unsuscriber;
+
+export class ActiviyTracker<Event> {
+  private observers = new Array<Listener<Event>>();
+  notify(data: Event) {
+    this.observers.forEach((observer) => observer(data))
+  }
+  subscribe(func: Listener<Event>): Unsuscriber {
+    this.observers.push(func);
+    return () => {
+      this.observers.forEach((observer, index) => {
+        if (observer === func) {
+          this.observers.splice(index, 1);
+        }
+      });
+    };
+  }
+}
+
+/**
+ * build http client with cache breaker due to SWR
+ * @param url
+ * @returns
+ */
+export interface APIClient<T, C> {
+  getRemoteConfig(): Promise<C>;
+  VERSION: string;
+  lib: T,
+  onActivity: Suscriber<ObservabilityEvent>;
+  cancelRequest(id: string): void;
+}
+
+export interface MerchantLib {
+  management: TalerMerchantManagementHttpClient;
+  authenticate: TalerAuthenticationHttpClient;
+  instance: (instanceId: string) => TalerMerchantInstanceHttpClient;
+  impersonate: (instanceId: string) => TalerAuthenticationHttpClient;
+}
+
+export interface BankLib {
+  bank: TalerCoreBankHttpClient;
+  conversion: TalerBankConversionHttpClient;
+  auth: (user: string) => TalerAuthenticationHttpClient;
+}
+
diff --git a/packages/web-util/src/context/bank-api.ts 
b/packages/web-util/src/context/bank-api.ts
new file mode 100644
index 000000000..645eda183
--- /dev/null
+++ b/packages/web-util/src/context/bank-api.ts
@@ -0,0 +1,202 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022-2024 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/>
+ */
+
+import {
+  CacheEvictor,
+  LibtoolVersion,
+  ObservabilityEvent,
+  ObservableHttpClientLibrary,
+  TalerAuthenticationHttpClient,
+  TalerBankConversionCacheEviction,
+  TalerBankConversionHttpClient,
+  TalerCoreBankCacheEviction,
+  TalerCoreBankHttpClient,
+  TalerCorebankApi,
+  TalerError
+} from "@gnu-taler/taler-util";
+import {
+  ComponentChildren,
+  FunctionComponent,
+  VNode,
+  createContext,
+  h,
+} from "preact";
+import { useContext, useEffect, useState } from "preact/hooks";
+import { APIClient, ActiviyTracker, BankLib, Suscriber } from "./activity.js";
+import { useTranslationContext } from "./translation.js";
+import { BrowserFetchHttpLib, ErrorLoading } from "../index.browser.js";
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+export type BankContextType = {
+  url: URL;
+  config: TalerCorebankApi.Config;
+  lib: BankLib;
+  hints: VersionHint[];
+  onActivity: Suscriber<ObservabilityEvent>;
+  cancelRequest: (eventId: string) => void;
+};
+
+// @ts-expect-error default value to undefined, should it be another thing?
+const BankContext = createContext<BankContextType>(undefined);
+
+export const useBankCoreApiContext = (): BankContextType => 
useContext(BankContext);
+
+enum VersionHint {
+  NONE,
+}
+
+type Evictors = {
+  conversion?: CacheEvictor<TalerBankConversionCacheEviction>;
+  bank?: CacheEvictor<TalerCoreBankCacheEviction>;
+}
+
+type ConfigResult<T> =
+  | undefined
+  | { type: "ok"; config: T; hints: VersionHint[] }
+  | { type: "incompatible"; result: T; supported: string }
+  | { type: "error"; error: TalerError };
+
+export const BankApiProvider = ({
+  baseUrl,
+  children,
+  frameOnError,
+  evictors = {},
+}: {
+  baseUrl: URL;
+  children: ComponentChildren;
+  evictors?: Evictors,
+  frameOnError: FunctionComponent<{ children: ComponentChildren }>;
+}): VNode => {
+  const [checked, setChecked] = 
useState<ConfigResult<TalerCorebankApi.Config>>();
+  const { i18n } = useTranslationContext();
+
+  const { getRemoteConfig, VERSION, lib, cancelRequest, onActivity } = 
buildBankApiClient(baseUrl, evictors);
+
+  useEffect(() => {
+    getRemoteConfig()
+      .then((config) => {
+        if (LibtoolVersion.compare(VERSION, config.version)) {
+          setChecked({ type: "ok", config, hints: [] });
+        } else {
+          setChecked({
+            type: "incompatible",
+            result: config,
+            supported: VERSION,
+          });
+        }
+      })
+      .catch((error: unknown) => {
+        if (error instanceof TalerError) {
+          setChecked({ type: "error", error });
+        }
+      });
+  }, []);
+
+  if (checked === undefined) {
+    return h(frameOnError, { children: h("div", {}, "checking compatibility 
with server...") });
+  }
+  if (checked.type === "error") {
+    return h(frameOnError, {
+      children: h(ErrorLoading, { error: checked.error, showDetail: true }),
+    });
+  }
+  if (checked.type === "incompatible") {
+    return h(frameOnError, {
+      children: h(
+        "div",
+        {},
+        i18n.str`The server version is not supported. Supported version 
"${checked.supported}", server version "${checked.result.version}"`,
+      ),
+    });
+  }
+
+  const value: BankContextType = {
+    url: baseUrl,
+    config: checked.config,
+    onActivity: onActivity,
+    lib,
+    cancelRequest,
+    hints: checked.hints,
+  };
+  return h(BankContext.Provider, {
+    value,
+    children,
+  });
+};
+
+function buildBankApiClient(url: URL, evictors: Evictors,
+): APIClient<BankLib, TalerCorebankApi.Config> {
+  const httpFetch = new BrowserFetchHttpLib({
+    enableThrottling: true,
+    requireTls: false,
+  });
+  const tracker = new ActiviyTracker<ObservabilityEvent>();
+  const httpLib = new ObservableHttpClientLibrary(httpFetch, {
+    observe(ev) {
+      tracker.notify(ev);
+    },
+  });
+
+  const bank = new TalerCoreBankHttpClient(
+    url.href,
+    httpLib,
+    evictors.bank,
+  );
+  const conversion = new TalerBankConversionHttpClient(
+    bank.getConversionInfoAPI().href,
+    httpLib,
+    evictors.conversion,
+  );
+  const auth = (user: string) =>
+    new TalerAuthenticationHttpClient(
+      bank.getAuthenticationAPI(user).href,
+      user,
+      httpLib,
+    );
+
+  async function getRemoteConfig() {
+    const resp = await bank.getConfig()
+    return resp.body
+  }
+
+  return {
+    getRemoteConfig,
+    VERSION: bank.PROTOCOL_VERSION,
+    lib: {
+      bank, conversion, auth
+    },
+    onActivity: tracker.subscribe,
+    cancelRequest: httpLib.cancelRequest,
+  };
+}
+
+
+export const BankApiProviderTesting = ({
+  children,
+  value,
+}: {
+  value: BankContextType
+  children: ComponentChildren;
+}): VNode => {
+  return h(BankContext.Provider, {
+    value,
+    children,
+  });
+}
diff --git a/packages/web-util/src/context/index.ts 
b/packages/web-util/src/context/index.ts
index 9ed3ef645..0e28b844a 100644
--- a/packages/web-util/src/context/index.ts
+++ b/packages/web-util/src/context/index.ts
@@ -4,4 +4,7 @@ export {
   TranslationProvider,
   useTranslationContext
 } from "./translation.js";
-
+export * from "./bank-api.js";
+export * from "./merchant-api.js";
+export * from "./navigation.js";
+export * from "./wallet-integration.js";
diff --git a/packages/web-util/src/context/merchant-api.ts 
b/packages/web-util/src/context/merchant-api.ts
new file mode 100644
index 000000000..79c79ee9c
--- /dev/null
+++ b/packages/web-util/src/context/merchant-api.ts
@@ -0,0 +1,226 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022-2024 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/>
+ */
+
+import {
+  CacheEvictor,
+  LibtoolVersion,
+  ObservabilityEvent,
+  ObservableHttpClientLibrary,
+  TalerAuthenticationHttpClient,
+  TalerError,
+  TalerMerchantApi,
+  TalerMerchantInstanceCacheEviction,
+  TalerMerchantInstanceHttpClient,
+  TalerMerchantManagementCacheEviction,
+  TalerMerchantManagementHttpClient,
+} from "@gnu-taler/taler-util";
+import {
+  ComponentChildren,
+  FunctionComponent,
+  VNode,
+  createContext,
+  h,
+} from "preact";
+import { useContext, useEffect, useState } from "preact/hooks";
+import {
+  APIClient,
+  ActiviyTracker,
+  MerchantLib,
+  Suscriber,
+} from "./activity.js";
+import { useTranslationContext } from "./translation.js";
+import { BrowserFetchHttpLib, ErrorLoading } from "../index.browser.js";
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+export type MerchantContextType = {
+  url: URL;
+  config: TalerMerchantApi.VersionResponse;
+  lib: MerchantLib;
+  hints: VersionHint[];
+  onActivity: Suscriber<ObservabilityEvent>;
+  cancelRequest: (eventId: string) => void;
+};
+
+// FIXME: below
+// @ts-expect-error default value to undefined, should it be another thing?
+const MerchantContext = createContext<MerchantContextType>(undefined);
+
+export const useMerchantApiContext = (): MerchantContextType =>
+  useContext(MerchantContext);
+
+enum VersionHint {
+  NONE,
+}
+
+type Evictors = {
+  management?: CacheEvictor<TalerMerchantManagementCacheEviction>;
+  instance?: (
+    instanceId: string,
+  ) => CacheEvictor<TalerMerchantInstanceCacheEviction>;
+};
+
+type ConfigResult<T> =
+  | undefined
+  | { type: "ok"; config: T; hints: VersionHint[] }
+  | { type: "incompatible"; result: T; supported: string }
+  | { type: "error"; error: TalerError };
+
+export const MerchantApiProvider = ({
+  baseUrl,
+  children,
+  evictors = {},
+  frameOnError,
+}: {
+  baseUrl: URL;
+  evictors?: Evictors;
+  children: ComponentChildren;
+  frameOnError: FunctionComponent<{ children: ComponentChildren }>;
+}): VNode => {
+  const [checked, setChecked] =
+    useState<ConfigResult<TalerMerchantApi.VersionResponse>>();
+  const { i18n } = useTranslationContext();
+
+  const { getRemoteConfig, VERSION, lib, cancelRequest, onActivity } =
+    buildMerchantApiClient(baseUrl, evictors);
+
+  useEffect(() => {
+    getRemoteConfig()
+      .then((config) => {
+        if (LibtoolVersion.compare(VERSION, config.version)) {
+          setChecked({ type: "ok", config, hints: [] });
+        } else {
+          setChecked({
+            type: "incompatible",
+            result: config,
+            supported: VERSION,
+          });
+        }
+      })
+      .catch((error: unknown) => {
+        if (error instanceof TalerError) {
+          setChecked({ type: "error", error });
+        }
+      });
+  }, []);
+
+  if (checked === undefined) {
+    return h(frameOnError, {
+      children: h("div", {}, "checking compatibility with server..."),
+    });
+  }
+  if (checked.type === "error") {
+    return h(frameOnError, {
+      children: h(ErrorLoading, { error: checked.error, showDetail: true }),
+    });
+  }
+  if (checked.type === "incompatible") {
+    return h(frameOnError, {
+      children: h(
+        "div",
+        {},
+        i18n.str`The server version is not supported. Supported version 
"${checked.supported}", server version "${checked.result.version}"`,
+      ),
+    });
+  }
+
+  const value: MerchantContextType = {
+    url: baseUrl,
+    config: checked.config,
+    onActivity: onActivity,
+    lib,
+    cancelRequest,
+    hints: checked.hints,
+  };
+  return h(MerchantContext.Provider, {
+    value,
+    children,
+  });
+};
+
+function buildMerchantApiClient(
+  url: URL,
+  evictors: Evictors,
+): APIClient<MerchantLib, TalerMerchantApi.VersionResponse> {
+  const httpFetch = new BrowserFetchHttpLib({
+    enableThrottling: true,
+    requireTls: false,
+  });
+  const tracker = new ActiviyTracker<ObservabilityEvent>();
+
+  const httpLib = new ObservableHttpClientLibrary(httpFetch, {
+    observe(ev) {
+      tracker.notify(ev);
+    },
+  });
+
+  const management = new TalerMerchantManagementHttpClient(
+    url.href,
+    httpLib,
+    evictors.management,
+  );
+  const instance = (instanceId: string) =>
+    new TalerMerchantInstanceHttpClient(
+      management.getSubInstanceAPI(instanceId).href,
+      httpLib,
+      evictors.instance ? evictors.instance(instanceId) : undefined,
+    );
+  const authenticate = new TalerAuthenticationHttpClient(
+    management.getAuthenticationAPI().href,
+    "default",
+    httpLib,
+  );
+  const impersonate = (instanceId: string) =>
+    new TalerAuthenticationHttpClient(
+      instance(instanceId).getAuthenticationAPI().href,
+      instanceId,
+      httpLib,
+    );
+
+  async function getRemoteConfig(): Promise<TalerMerchantApi.VersionResponse> {
+    const resp = await management.getConfig();
+    return resp.body;
+  }
+
+  return {
+    getRemoteConfig,
+    VERSION: management.PROTOCOL_VERSION,
+    lib: {
+      management,
+      authenticate,
+      impersonate,
+      instance,
+    },
+    onActivity: tracker.subscribe,
+    cancelRequest: httpLib.cancelRequest,
+  };
+}
+
+export const MerchantApiProviderTesting = ({
+  children,
+  value,
+}: {
+  value: MerchantContextType;
+  children: ComponentChildren;
+}): VNode => {
+  return h(MerchantContext.Provider, {
+    value,
+    children,
+  });
+};
diff --git a/packages/web-util/src/context/navigation.ts 
b/packages/web-util/src/context/navigation.ts
new file mode 100644
index 000000000..a2fe3ff12
--- /dev/null
+++ b/packages/web-util/src/context/navigation.ts
@@ -0,0 +1,102 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022-2024 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/>
+ */
+
+import { ComponentChildren, createContext, h, VNode } from "preact";
+import { useContext, useEffect, useState } from "preact/hooks";
+import { AppLocation, ObjectOf, Location, findMatch, RouteDefinition } from 
"../utils/route.js";
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export function useCurrentLocation<T extends ObjectOf<RouteDefinition<any>>>(
+  pagesMap: T,
+): Location<T> | undefined {
+  const pageList = Object.keys(pagesMap as object) as Array<keyof T>;
+  const { path, params } = useNavigationContext();
+
+  return findMatch(pagesMap, pageList, path, params);
+}
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+export type Type = {
+  path: string;
+  params: Record<string, string>;
+  navigateTo: (path: AppLocation) => void;
+  // addNavigationListener: (listener: (path: string, params: Record<string, 
string>) => void) => (() => void);
+};
+
+// @ts-expect-error should not be used without provider
+const Context = createContext<Type>(undefined);
+
+export const useNavigationContext = (): Type => useContext(Context);
+
+function getPathAndParamsFromWindow() {
+  const path =
+    typeof window !== "undefined" ? window.location.hash.substring(1) : "/";
+  const params: Record<string, string> = {};
+  if (typeof window !== "undefined") {
+    for (const [key, value] of new URLSearchParams(window.location.search)) {
+      params[key] = value;
+    }
+  }
+  return { path, params };
+}
+
+const { path: initialPath, params: initialParams } =
+  getPathAndParamsFromWindow();
+
+// there is a possibility that if the browser does a redirection
+// (which doesn't go through navigatTo function) and that executed
+// too early (before addEventListener runs) it won't be taking
+// into account
+const PopStateEventType = "popstate";
+
+export const BrowserHashNavigationProvider = ({
+  children,
+}: {
+  children: ComponentChildren;
+}): VNode => {
+  const [{ path, params }, setState] = useState({
+    path: initialPath,
+    params: initialParams,
+  });
+  if (typeof window === "undefined") {
+    throw Error(
+      "Can't use BrowserHashNavigationProvider if there is no window object",
+    );
+  }
+  function navigateTo(path: string) {
+    const { params } = getPathAndParamsFromWindow();
+    setState({ path, params });
+    window.location.href = path;
+  }
+
+  useEffect(() => {
+    function eventListener() {
+      setState(getPathAndParamsFromWindow());
+    }
+    window.addEventListener(PopStateEventType, eventListener);
+    return () => {
+      window.removeEventListener(PopStateEventType, eventListener);
+    };
+  }, []);
+  return h(Context.Provider, {
+    value: { path, params, navigateTo },
+    children,
+  });
+};
diff --git a/packages/web-util/src/context/wallet-integration.ts 
b/packages/web-util/src/context/wallet-integration.ts
new file mode 100644
index 000000000..e14988ed1
--- /dev/null
+++ b/packages/web-util/src/context/wallet-integration.ts
@@ -0,0 +1,83 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022-2024 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/>
+ */
+
+import { stringifyTalerUri, TalerUri } from "@gnu-taler/taler-util";
+import { ComponentChildren, createContext, h, VNode } from "preact";
+import { useContext } from "preact/hooks";
+
+/**
+ * https://docs.taler.net/design-documents/039-taler-browser-integration.html
+ *
+ * @param uri
+ */
+function createHeadMetaTag(uri: TalerUri, onNotFound?: () => void) {
+  const meta = document.createElement("meta");
+  meta.setAttribute("name", "taler-uri");
+  meta.setAttribute("content", stringifyTalerUri(uri));
+
+  document.head.appendChild(meta);
+
+  let walletFound = false;
+  window.addEventListener("beforeunload", () => {
+    walletFound = true;
+  });
+  setTimeout(() => {
+    if (!walletFound && onNotFound) {
+      onNotFound();
+    }
+  }, 10); //very short timeout
+}
+interface Type {
+  /**
+   * Tell the active wallet that an action is found
+   *
+   * @param uri
+   * @returns
+   */
+  publishTalerAction: (uri: TalerUri, onNotFound?: () => void) => void;
+}
+
+// @ts-expect-error default value to undefined, should it be another thing?
+const Context = createContext<Type>(undefined);
+
+export const useTalerWalletIntegrationAPI = (): Type => useContext(Context);
+
+export const TalerWalletIntegrationBrowserProvider = ({
+  children,
+}: {
+  children: ComponentChildren;
+}): VNode => {
+  const value: Type = {
+    publishTalerAction: createHeadMetaTag,
+  };
+  return h(Context.Provider, {
+    value,
+    children,
+  });
+};
+
+export const TalerWalletIntegrationTestingProvider = ({
+  children,
+  value,
+}: {
+  children: ComponentChildren;
+  value: Type;
+}): VNode => {
+  return h(Context.Provider, {
+    value,
+    children,
+  });
+};
diff --git a/packages/web-util/src/index.browser.ts 
b/packages/web-util/src/index.browser.ts
index 82c399bfd..2f3b57b8d 100644
--- a/packages/web-util/src/index.browser.ts
+++ b/packages/web-util/src/index.browser.ts
@@ -3,6 +3,7 @@ export * from "./utils/request.js";
 export * from "./utils/http-impl.browser.js";
 export * from "./utils/http-impl.sw.js";
 export * from "./utils/observable.js";
+export * from "./utils/route.js";
 export * from "./context/index.js";
 export * from "./components/index.js";
 export * from "./forms/index.js";
diff --git a/packages/web-util/src/utils/route.ts 
b/packages/web-util/src/utils/route.ts
new file mode 100644
index 000000000..4f8a020f6
--- /dev/null
+++ b/packages/web-util/src/utils/route.ts
@@ -0,0 +1,129 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022-2024 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/>
+ */
+
+declare const __location: unique symbol;
+/**
+ * special string that defined a location in the application
+ *
+ * this help to prevent wrong path
+ */
+export type AppLocation = string & {
+  [__location]: true;
+};
+
+export type EmptyObject = Record<string, never>;
+
+export function urlPattern<
+  T extends Record<string, string | undefined> = EmptyObject,
+>(pattern: RegExp, reverse: (p: T) => string): RouteDefinition<T> {
+  const url = reverse as (p: T) => AppLocation;
+  return {
+    pattern: new RegExp(pattern),
+    url,
+  };
+}
+
+/**
+ * defines a location in the app
+ *
+ * pattern: how a string will trigger this location
+ * url(): how a state serialize to a location
+ */
+
+export type ObjectOf<T> = Record<string, T> | EmptyObject;
+
+export type RouteDefinition<
+  T extends ObjectOf<string | undefined> = EmptyObject,
+> = {
+  pattern: RegExp;
+  url: (p: T) => AppLocation;
+};
+
+const nullRountDef = {
+  pattern: new RegExp(/.*/),
+  url: () => "" as AppLocation,
+};
+export function buildNullRoutDefinition<
+  T extends ObjectOf<string>,
+>(): RouteDefinition<T> {
+  return nullRountDef;
+}
+
+/**
+ * Search path in the pageList
+ * get the values from the path found
+ * add params from searchParams
+ *
+ * @param path
+ * @param params
+ */
+export function findMatch<T extends ObjectOf<RouteDefinition>>(
+  pagesMap: T,
+  pageList: Array<keyof T>,
+  path: string,
+  params: Record<string, string>,
+): Location<T> | undefined {
+  for (let idx = 0; idx < pageList.length; idx++) {
+    const name = pageList[idx];
+    const found = pagesMap[name].pattern.exec(path);
+    if (found !== null) {
+      const values = {} as Record<string, unknown>;
+
+      Object.entries(params).forEach(([key, value]) => {
+        values[key] = value;
+      });
+
+      if (found.groups !== undefined) {
+        Object.entries(found.groups).forEach(([key, value]) => {
+          values[key] = value;
+        });
+      }
+
+      // @ts-expect-error values is a map string which is equivalent to the 
RouteParamsType
+      return { name, parent: pagesMap, values };
+    }
+  }
+  return undefined;
+}
+
+/**
+ * get the type of the params of a location
+ *
+ */
+type RouteParamsType<
+  RouteType,
+  Key extends keyof RouteType,
+> = RouteType[Key] extends RouteDefinition<infer ParamType> ? ParamType : 
never;
+
+/**
+ * Helps to create a map of a type with the key
+ */
+type MapKeyValue<Type> = {
+  [Key in keyof Type]: Key extends string
+  ? {
+    parent: Type;
+    name: Key;
+    values: RouteParamsType<Type, Key>;
+  }
+  : never;
+};
+
+/**
+ * create a enumeration of value of a mapped type
+ */
+type EnumerationOf<T> = T[keyof T];
+
+export type Location<T> = EnumerationOf<MapKeyValue<T>>;

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