gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated (5a1f528d8 -> dd5aa2145)


From: gnunet
Subject: [taler-wallet-core] branch master updated (5a1f528d8 -> dd5aa2145)
Date: Tue, 26 Mar 2024 20:58:47 +0100

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

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

    from 5a1f528d8 idb-bridge: primitive benchmarking entry point
     new 8aa9ce6d2 wip
     new a427958be wip
     new 3057dcfeb wip
     new 0c265558c how to do a prebuilt
     new e2bfbced7 work in progress, new api being used. merchant now should 
move into using the full API
     new 5181d060c wip, doesn't compile. now merchant doesn't have it's own 
definition of types... it uses the one defined by taler-util
     new af633723b fixing compile errors
     new dd5aa2145 fix #8660

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


Summary of changes:
 README                                             |  20 +
 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             |  25 +-
 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           |  43 +-
 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    |   8 +-
 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     |   6 +-
 .../merchant-backoffice-ui/src/Application.tsx     | 227 ++++-----
 .../src/ApplicationReadyRoutes.tsx                 | 174 -------
 .../src/{InstanceRoutes.tsx => Routing.tsx}        | 284 +++++------
 .../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          |  10 +-
 .../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         |   6 +-
 .../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             |   8 +-
 .../src/components/form/InputTab.tsx               |   2 +-
 .../src/components/form/InputTaxes.tsx             |   6 +-
 .../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         |  16 +-
 .../src/components/menu/LangSelector.tsx           |   2 +-
 .../src/components/menu/NavigationBar.tsx          |   2 +-
 .../src/components/menu/SideBar.tsx                |  68 ++-
 .../src/components/menu/index.tsx                  |  93 ++--
 .../src/components/modal/index.tsx                 |  16 +-
 .../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    |  10 +-
 .../components/product/NonInventoryProductForm.tsx |  16 +-
 .../src/components/product/ProductForm.tsx         |  34 +-
 .../src/components/product/ProductList.tsx         |  11 +-
 .../src/context/backend.test.ts                    | 163 ------
 .../merchant-backoffice-ui/src/context/backend.ts  |  69 ---
 .../merchant-backoffice-ui/src/context/config.ts   |  29 --
 .../merchant-backoffice-ui/src/context/instance.ts |   7 +-
 .../merchant-backoffice-ui/src/context/session.ts  | 252 +++++++++
 .../src/context/settings.ts                        |  10 +-
 packages/merchant-backoffice-ui/src/custom.d.ts    |   2 +-
 .../merchant-backoffice-ui/src/declaration.d.ts    |  31 +-
 packages/merchant-backoffice-ui/src/hooks/async.ts |   2 +-
 .../merchant-backoffice-ui/src/hooks/backend.ts    | 276 ++++------
 packages/merchant-backoffice-ui/src/hooks/bank.ts  |  34 +-
 packages/merchant-backoffice-ui/src/hooks/index.ts | 151 ------
 .../src/hooks/instance.test.ts                     | 103 ++--
 .../merchant-backoffice-ui/src/hooks/instance.ts   | 179 ++++---
 .../merchant-backoffice-ui/src/hooks/listener.ts   |   2 +-
 .../merchant-backoffice-ui/src/hooks/merchant.ts   |  34 +-
 .../src/hooks/notifications.ts                     |   2 +-
 .../merchant-backoffice-ui/src/hooks/order.test.ts |  43 +-
 packages/merchant-backoffice-ui/src/hooks/order.ts |  58 +--
 packages/merchant-backoffice-ui/src/hooks/otp.ts   |  47 +-
 .../merchant-backoffice-ui/src/hooks/preference.ts |  86 ++++
 .../src/hooks/product.test.ts                      |  46 +-
 .../merchant-backoffice-ui/src/hooks/product.ts    |  36 +-
 .../src/hooks/reserve.test.ts                      | 207 --------
 .../merchant-backoffice-ui/src/hooks/reserves.ts   |  94 ----
 .../merchant-backoffice-ui/src/hooks/templates.ts  |  72 +--
 .../merchant-backoffice-ui/src/hooks/testing.tsx   |  26 +-
 .../src/hooks/transfer.test.ts                     |  12 +-
 .../merchant-backoffice-ui/src/hooks/transfer.ts   |  28 +-
 packages/merchant-backoffice-ui/src/hooks/urls.ts  | 122 +----
 .../src/hooks/useSettings.ts                       |  73 ---
 .../merchant-backoffice-ui/src/hooks/webhooks.ts   |  33 +-
 packages/merchant-backoffice-ui/src/index.html     |   2 +-
 packages/merchant-backoffice-ui/src/index.tsx      |   8 +-
 .../src/paths/admin/create/Create.stories.tsx      |  33 +-
 .../src/paths/admin/create/CreatePage.tsx          |  13 +-
 .../admin/create/InstanceCreatedSuccessfully.tsx   |   2 +-
 .../src/paths/admin/create/index.tsx               |  47 +-
 .../src/paths/admin/create/stories.tsx             |  35 +-
 .../src/paths/admin/index.stories.ts               |   2 +-
 .../src/paths/admin/list/TableActive.tsx           |  30 +-
 .../src/paths/admin/list/View.stories.tsx          |   2 +-
 .../src/paths/admin/list/View.tsx                  |  13 +-
 .../src/paths/admin/list/index.tsx                 |  18 +-
 .../instance/accounts/create/Create.stories.tsx    |   2 +-
 .../paths/instance/accounts/create/CreatePage.tsx  |  10 +-
 .../src/paths/instance/accounts/create/index.tsx   |   8 +-
 .../paths/instance/accounts/list/List.stories.tsx  |   2 +-
 .../src/paths/instance/accounts/list/ListPage.tsx  |  13 +-
 .../src/paths/instance/accounts/list/Table.tsx     |  12 +-
 .../src/paths/instance/accounts/list/index.tsx     |  12 +-
 .../instance/accounts/update/Update.stories.tsx    |   2 +-
 .../paths/instance/accounts/update/UpdatePage.tsx  |  16 +-
 .../src/paths/instance/accounts/update/index.tsx   |   9 +-
 .../src/paths/instance/details/DetailPage.tsx      |  10 +-
 .../src/paths/instance/details/index.tsx           |  13 +-
 .../src/paths/instance/details/stories.tsx         |  37 +-
 .../src/paths/instance/index.stories.ts            |   2 +-
 .../paths/instance/kyc/list/ListPage.stories.tsx   |  15 +-
 .../src/paths/instance/kyc/list/ListPage.tsx       |  10 +-
 .../src/paths/instance/kyc/list/index.tsx          |   7 +-
 .../instance/orders/create/Create.stories.tsx      |   2 +-
 .../paths/instance/orders/create/CreatePage.tsx    | 564 ++++++++++++---------
 .../orders/create/OrderCreatedSuccessfully.tsx     |   2 +-
 .../src/paths/instance/orders/create/index.tsx     |  15 +-
 .../instance/orders/details/Detail.stories.tsx     |  35 +-
 .../paths/instance/orders/details/DetailPage.tsx   |  90 ++--
 .../src/paths/instance/orders/details/Timeline.tsx |   6 +-
 .../src/paths/instance/orders/details/index.tsx    |  13 +-
 .../paths/instance/orders/list/List.stories.tsx    |  13 +-
 .../src/paths/instance/orders/list/ListPage.tsx    |  16 +-
 .../src/paths/instance/orders/list/Table.tsx       |  52 +-
 .../src/paths/instance/orders/list/index.tsx       |  17 +-
 .../instance/otp_devices/create/Create.stories.tsx |   2 +-
 .../instance/otp_devices/create/CreatePage.tsx     |  11 +-
 .../otp_devices/create/CreatedSuccessfully.tsx     |  23 +-
 .../paths/instance/otp_devices/create/index.tsx    |  13 +-
 .../instance/otp_devices/list/List.stories.tsx     |   2 +-
 .../paths/instance/otp_devices/list/ListPage.tsx   |  13 +-
 .../src/paths/instance/otp_devices/list/Table.tsx  |  11 +-
 .../src/paths/instance/otp_devices/list/index.tsx  |   9 +-
 .../instance/otp_devices/update/Update.stories.tsx |   2 +-
 .../instance/otp_devices/update/UpdatePage.tsx     |   7 +-
 .../paths/instance/otp_devices/update/index.tsx    |  19 +-
 .../instance/products/create/Create.stories.tsx    |   2 +-
 .../paths/instance/products/create/CreatePage.tsx  |   6 +-
 .../products/create/CreatedSuccessfully.tsx        |   2 +-
 .../src/paths/instance/products/create/index.tsx   |   8 +-
 .../paths/instance/products/list/List.stories.tsx  |   7 +-
 .../src/paths/instance/products/list/Table.tsx     |  25 +-
 .../src/paths/instance/products/list/index.tsx     |  17 +-
 .../instance/products/update/Update.stories.tsx    |   9 +-
 .../paths/instance/products/update/UpdatePage.tsx  |   6 +-
 .../src/paths/instance/products/update/index.tsx   |  11 +-
 .../instance/templates/create/Create.stories.tsx   |   2 +-
 .../paths/instance/templates/create/CreatePage.tsx | 226 +++++----
 .../src/paths/instance/templates/create/index.tsx  |   8 +-
 .../paths/instance/templates/list/List.stories.tsx |   2 +-
 .../src/paths/instance/templates/list/ListPage.tsx |  17 +-
 .../src/paths/instance/templates/list/Table.tsx    |  11 +-
 .../src/paths/instance/templates/list/index.tsx    |  19 +-
 .../src/paths/instance/templates/qr/Qr.stories.tsx |   2 +-
 .../src/paths/instance/templates/qr/QrPage.tsx     |  43 +-
 .../src/paths/instance/templates/qr/index.tsx      |  17 +-
 .../instance/templates/update/Update.stories.tsx   |   2 +-
 .../paths/instance/templates/update/UpdatePage.tsx |  22 +-
 .../src/paths/instance/templates/update/index.tsx  |  11 +-
 .../paths/instance/templates/use/Use.stories.tsx   |   2 +-
 .../src/paths/instance/templates/use/UsePage.tsx   |   8 +-
 .../src/paths/instance/templates/use/index.tsx     |  13 +-
 .../src/paths/instance/token/DetailPage.tsx        |  51 +-
 .../src/paths/instance/token/index.tsx             |  49 +-
 .../src/paths/instance/token/stories.tsx           |   2 +-
 .../instance/transfers/create/Create.stories.tsx   |   2 +-
 .../paths/instance/transfers/create/CreatePage.tsx |  12 +-
 .../src/paths/instance/transfers/create/index.tsx  |  11 +-
 .../paths/instance/transfers/list/List.stories.tsx |  17 +-
 .../src/paths/instance/transfers/list/ListPage.tsx |   6 +-
 .../src/paths/instance/transfers/list/Table.tsx    |  15 +-
 .../src/paths/instance/transfers/list/index.tsx    |  12 +-
 .../src/paths/instance/transfers/update/index.tsx  |   2 +-
 .../src/paths/instance/update/Update.stories.tsx   |   6 +-
 .../src/paths/instance/update/UpdatePage.tsx       |  25 +-
 .../src/paths/instance/update/index.tsx            |  17 +-
 .../instance/webhooks/create/Create.stories.tsx    |   2 +-
 .../paths/instance/webhooks/create/CreatePage.tsx  |  10 +-
 .../src/paths/instance/webhooks/create/index.tsx   |   8 +-
 .../paths/instance/webhooks/list/List.stories.tsx  |   2 +-
 .../src/paths/instance/webhooks/list/ListPage.tsx  |  10 +-
 .../src/paths/instance/webhooks/list/Table.tsx     |  11 +-
 .../src/paths/instance/webhooks/list/index.tsx     |   9 +-
 .../instance/webhooks/update/Update.stories.tsx    |   2 +-
 .../paths/instance/webhooks/update/UpdatePage.tsx  |   7 +-
 .../src/paths/instance/webhooks/update/index.tsx   |   9 +-
 .../src/paths/login/index.tsx                      | 386 ++++++++------
 .../src/paths/notfound/index.tsx                   |   2 +-
 .../src/paths/settings/index.tsx                   | 206 ++++----
 .../merchant-backoffice-ui/src/schemas/index.ts    |   6 +-
 .../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     |  10 +-
 .../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 |   3 +-
 packages/merchant-backoffice-ui/src/utils/types.ts |   4 +-
 .../create_merchantAndBankAccount_pdf.sh           |  23 +
 packages/taler-harness/pdf-template.html           |  65 +++
 packages/taler-harness/src/index.ts                | 393 ++++++++++++--
 .../taler-util/src/http-client/authentication.ts   |  36 +-
 packages/taler-util/src/http-client/bank-core.ts   |  12 +-
 packages/taler-util/src/http-client/merchant.ts    | 415 ++++++++++++---
 packages/taler-util/src/http-client/types.ts       |  23 +-
 packages/taler-util/src/http-common.ts             |   1 +
 packages/taler-util/src/http-impl.node.ts          |   9 +-
 packages/taler-util/src/http-impl.qtart.ts         |   8 +-
 packages/taler-util/src/index.ts                   |   1 +
 packages/taler-util/src/taler-types.ts             |   1 +
 packages/web-util/src/context/activity.ts          |  65 +++
 packages/web-util/src/context/bank-api.ts          | 201 ++++++++
 packages/web-util/src/context/index.ts             |   5 +-
 packages/web-util/src/context/merchant-api.ts      | 224 ++++++++
 .../src/context/navigation.ts                      |  12 +-
 .../src/context/wallet-integration.ts              |   0
 packages/web-util/src/index.browser.ts             |   1 +
 .../{bank-ui/src => web-util/src/utils}/route.ts   |  28 +-
 282 files changed, 4483 insertions(+), 4055 deletions(-)
 delete mode 100644 
packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx
 rename packages/merchant-backoffice-ui/src/{InstanceRoutes.tsx => Routing.tsx} 
(80%)
 delete mode 100644 packages/merchant-backoffice-ui/src/context/backend.test.ts
 delete mode 100644 packages/merchant-backoffice-ui/src/context/backend.ts
 delete mode 100644 packages/merchant-backoffice-ui/src/context/config.ts
 create mode 100644 packages/merchant-backoffice-ui/src/context/session.ts
 copy packages/{bank-ui => merchant-backoffice-ui}/src/context/settings.ts (85%)
 delete mode 100644 packages/merchant-backoffice-ui/src/hooks/index.ts
 create mode 100644 packages/merchant-backoffice-ui/src/hooks/preference.ts
 delete mode 100644 packages/merchant-backoffice-ui/src/hooks/reserve.test.ts
 delete mode 100644 packages/merchant-backoffice-ui/src/hooks/reserves.ts
 delete mode 100644 packages/merchant-backoffice-ui/src/hooks/useSettings.ts
 copy packages/{bank-ui => merchant-backoffice-ui}/src/settings.ts (51%)
 create mode 100644 packages/taler-harness/create_merchantAndBankAccount_pdf.sh
 create mode 100644 packages/taler-harness/pdf-template.html
 create mode 100644 packages/web-util/src/context/activity.ts
 create mode 100644 packages/web-util/src/context/bank-api.ts
 create mode 100644 packages/web-util/src/context/merchant-api.ts
 copy packages/{bank-ui => web-util}/src/context/navigation.ts (86%)
 copy packages/{bank-ui => web-util}/src/context/wallet-integration.ts (100%)
 copy packages/{bank-ui/src => web-util/src/utils}/route.ts (82%)

diff --git a/README b/README
index 4bf368726..471815c0b 100644
--- a/README
+++ b/README
@@ -27,6 +27,26 @@ The CLI version of the wallet supports the normal GNU 
installation process.
 If you are compiling the code from git, you have to run `./bootstrap` before
 running `./configure`.
 
+## Pushing a new prebuilt version
+
+After compiling run
+
+```shell
+make prebuilt
+```
+
+This will create a directory `prebuilt` with a git subtree, 
+compile every prebuilt project, copy everything into this subtree
+and create a commit with the default message mentioning from
+which revision the prebuilt was created.
+When the script completes the prebuilt version can should
+be manually pushed.
+
+```shell
+cd prebuilt
+git push
+```
+
 ### Building the WebExtension
 
 The WebExtension can be built via the 'webextension' make target:
diff --git a/packages/bank-ui/src/Routing.tsx b/packages/bank-ui/src/Routing.tsx
index fbf5aa9ec..3ec5f0c77 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).createAccessTokenBasic(username, 
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..86b6df5f3 100644
--- a/packages/bank-ui/src/context/config.ts
+++ b/packages/bank-ui/src/context/config.ts
@@ -218,7 +218,6 @@ function buildApiClient(url: URL) {
   const authClient = (user: string) =>
     new TalerAuthenticationHttpClient(
       bankClient.getAuthenticationAPI(user).href,
-      user,
       httpLib,
     );
 
@@ -251,7 +250,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(),
@@ -305,15 +304,15 @@ const evictBankSwrCache: 
CacheEvictor<TalerCoreBankCacheEviction> = {
 };
 
 const evictConversionSwrCache: CacheEvictor<TalerBankConversionCacheEviction> =
-  {
-    async notifySuccess(op) {
-      switch (op) {
-        case TalerBankConversionCacheEviction.UPDATE_RATE: {
-          await revalidateConversionInfo();
-          return;
-        }
-        default:
-          assertUnreachable(op);
+{
+  async notifySuccess(op) {
+    switch (op) {
+      case TalerBankConversionCacheEviction.UPDATE_RATE: {
+        await revalidateConversionInfo();
+        return;
       }
-    },
-  };
+      default:
+        assertUnreachable(op);
+    }
+  },
+};
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..7eed0cd9e 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,24 @@ 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).createAccessTokenBasic(username, password, {
+            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..dc08ce0fa 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();
 
@@ -114,7 +114,7 @@ function RegistrationForm({
     onComplete: () => void,
   ) {
     await handleError(async (onError) => {
-      const resp = await api.createAccount("" as AccessToken, {
+      const resp = await api.createAccount(undefined, {
         name,
         username,
         password,
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..b186f1408 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 "./Routing.js";
 
 export enum AdminPaths {
   list_instances = "/instances",
@@ -46,8 +46,6 @@ export function AdminRoutes(): VNode {
           route(InstancePaths.bank_list);
         }}
 
-        // onError={(error: any) => {
-        // }}
       />
     </Router>
   );
diff --git a/packages/merchant-backoffice-ui/src/Application.tsx 
b/packages/merchant-backoffice-ui/src/Application.tsx
index cf46a34d5..d752d612d 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 { VNode, h } from "preact";
+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
deleted file mode 100644
index 3dc34d1a9..000000000
--- a/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-import { HttpStatusCode, TranslatedString } 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 {
-  NotConnectedAppMenu,
-  NotYetReadyAppMenu,
-  NotificationCard,
-} from "./components/menu/index.js";
-import { useBackendContext } from "./context/backend.js";
-import { LoginToken } from "./declaration.js";
-import { useBackendInstancesTestForAdmin } from "./hooks/backend.js";
-import { LoginPage } from "./paths/login/index.js";
-import { Settings } from "./paths/settings/index.js";
-import { INSTANCE_ID_LOOKUP } from "./utils/constants.js";
-
-/**
- * Check if admin against /management/instances
- * @returns 
- */
-export function ApplicationReadyRoutes(): VNode {
-  const { i18n } = useTranslationContext();
-  const [unauthorized, setUnauthorized] = useState(false)
-  const {
-    url: backendURL,
-    updateToken,
-    alreadyTriedLogin,
-  } = useBackendContext();
-
-  function updateLoginStatus(token: LoginToken | undefined) {
-    updateToken(token)
-    setUnauthorized(false)
-  }
-  const result = useBackendInstancesTestForAdmin();
-
-  const clearTokenAndGoToRoot = () => {
-    route("/");
-  };
-  const [showSettings, setShowSettings] = useState(false)
-  const unauthorizedAdmin = !result.loading
-    && !result.ok
-    && result.type === ErrorType.CLIENT
-    && result.status === HttpStatusCode.Unauthorized;
-
-  if (!alreadyTriedLogin && !result.ok) {
-    return (
-      <Fragment>
-        <NotConnectedAppMenu title="Welcome!" />
-        <LoginPage onConfirm={updateToken} />
-      </Fragment>
-    );
-  }
-
-  if (showSettings) {
-    return <Fragment>
-      <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} 
title="UI Settings" onLogout={clearTokenAndGoToRoot} isPasswordOk={false} />
-      <Settings onClose={() => setShowSettings(false)} />
-    </Fragment>
-  }
-
-  if (result.loading) {
-    return <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} 
title="Loading..." isPasswordOk={false} />;
-  }
-
-  let admin = result.ok || unauthorizedAdmin;
-  let instanceNameByBackendURL: string | undefined;
-
-  if (!admin) {
-    // * the testing against admin endpoint failed and it's not 
-    // an authorization problem
-    // * merchant backend will return this SPA under the main
-    // endpoint or /instance/<id> endpoint
-    // => trying to infer the instance id
-    const path = new URL(backendURL).pathname;
-    const match = INSTANCE_ID_LOOKUP.exec(path);
-    if (!match || !match[1]) {
-      // this should be rare because
-      // query to /config is ok but the URL
-      // does not match our pattern
-      return (
-        <Fragment>
-          <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} 
title="Error" onLogout={clearTokenAndGoToRoot} isPasswordOk={false} />
-          <NotificationCard
-            notification={{
-              message: i18n.str`Couldn't access the server.`,
-              description: i18n.str`Could not infer instance id from url 
${backendURL}`,
-              type: "ERROR",
-            }}
-          />
-          {/* <ConnectionPage onConfirm={changeBackend} /> */}
-        </Fragment>
-      );
-    }
-
-    instanceNameByBackendURL = match[1];
-  }
-
-  if (unauthorized || unauthorizedAdmin) {
-    return <Fragment>
-      <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} 
title="Login" onLogout={clearTokenAndGoToRoot} isPasswordOk={false} />
-      <NotificationCard
-        notification={{
-          message: i18n.str`Access denied`,
-          description: i18n.str`Check your token is valid`,
-          type: "ERROR",
-        }}
-      />
-      <LoginPage onConfirm={updateLoginStatus} />
-    </Fragment>
-  }
-
-  const history = createHashHistory();
-  return (
-    <Router history={history}>
-      <Route
-        default
-        component={DefaultMainRoute}
-        admin={admin}
-        onUnauthorized={() => setUnauthorized(true)}
-        onLoginPass={() => {
-          setUnauthorized(false)
-        }}
-        instanceNameByBackendURL={instanceNameByBackendURL}
-      />
-    </Router>
-  );
-}
-
-function DefaultMainRoute({
-  instance,
-  admin,
-  onUnauthorized,
-  onLoginPass,
-  instanceNameByBackendURL,
-  url, //from preact-router
-}: any): VNode {
-  const [instanceName, setInstanceName] = useState(
-    instanceNameByBackendURL || instance || "default",
-  );
-
-  return (
-    <InstanceRoutes
-      admin={admin}
-      path={url}
-      onUnauthorized={onUnauthorized}
-      onLoginPass={onLoginPass}
-      id={instanceName}
-      setInstanceName={setInstanceName}
-    />
-  );
-}
diff --git a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx 
b/packages/merchant-backoffice-ui/src/Routing.tsx
similarity index 80%
rename from packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
rename to packages/merchant-backoffice-ui/src/Routing.tsx
index edc1d9a11..c30b1912a 100644
--- a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
+++ b/packages/merchant-backoffice-ui/src/Routing.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,29 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { TranslatedString } from "@gnu-taler/taler-util";
+import { AbsoluteTime, TalerErrorDetail, 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 { useEffect, useErrorBoundary, useState } from "preact/hooks";
 import { Loading } from "./components/exception/loading.js";
-import { Menu, 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";
+  Menu,
+  NotConnectedAppMenu,
+  NotificationCard,
+} from "./components/menu/index.js";
+import { useInstanceBankAccounts } from "./hooks/bank.js";
 import { useInstanceKYCDetails } from "./hooks/instance.js";
-import { dateFormatForSettings, useSettings } from "./hooks/useSettings.js";
+import { usePreference } from "./hooks/preference.js";
+import {
+  DEFAULT_ADMIN_USERNAME,
+  useSessionContext,
+} from "./context/session.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 +76,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 { createHashHistory } from "history";
 
 export enum InstancePaths {
   error = "/error",
@@ -120,7 +122,7 @@ export enum InstancePaths {
 }
 
 // eslint-disable-next-line @typescript-eslint/no-empty-function
-const noop = () => { };
+const noop = () => {};
 
 export enum AdminPaths {
   list_instances = "/instances",
@@ -128,53 +130,40 @@ 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"),
+};
+
+const history = createHashHistory();
+export function Routing(_p: Props): VNode {
   const { i18n } = useTranslationContext();
+  const { state } = useSessionContext();
 
-  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 [error] = useErrorBoundary();
 
-  const value = useMemo(
-    () => ({ id, token, admin, changeToken }),
-    [id, token, admin],
-  );
-
   const instance = useInstanceBankAccounts();
   const accounts = !instance.ok ? undefined : instance.data.accounts;
+  const shouldWarnAboutMissingBankAccounts =
+    !state.isAdmin && accounts !== undefined && accounts.length < 1;
+  const shouldLogin =
+    state.status === "loggedOut" || state.status === "expired";
 
   function ServerErrorRedirectTo(to: InstancePaths | AdminPaths) {
     return function ServerErrorRedirectToImpl(
-      error: HttpError<MerchantBackend.ErrorDetail>,
+      error: HttpError<TalerErrorDetail>,
     ) {
       if (error.type === ErrorType.TIMEOUT) {
         setGlobalNotification({
@@ -189,7 +178,7 @@ export function InstanceRoutes({
           description: i18n.str`Diagnostic from ${error.info.url} is 
'${error.message}'`,
           details:
             error.type === ErrorType.CLIENT || error.type === ErrorType.SERVER
-              ? error.payload.detail
+              ? error.payload.hint
               : undefined,
           type: "ERROR",
           to,
@@ -201,22 +190,23 @@ 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") {
+      if (state.isAdmin && state.instance === DEFAULT_ADMIN_USERNAME) {
         return (
           <Fragment>
             <NotificationCard
@@ -227,7 +217,7 @@ export function InstanceRoutes({
               }}
             />
             <InstanceCreatePage
-              forceId="default"
+              forceId={DEFAULT_ADMIN_USERNAME}
               onConfirm={() => {
                 route(InstancePaths.bank_list);
               }}
@@ -242,61 +232,56 @@ export function InstanceRoutes({
     };
   }
 
-  const clearTokenAndGoToRoot = () => {
-    route("/");
-    // clear all tokens
-    updateToken(undefined)
-    updateDefaultToken(undefined)
-  };
+  if (shouldLogin) {
+    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>
+  if (shouldWarnAboutMissingBankAccounts) {
+    return (
+      <Fragment>
+        <Menu />
+        <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}>
-      <Menu
-        instance={id}
-        admin={admin}
-        onShowSettings={() => {
-          route(InstancePaths.interface)
-        }}
-        path={path}
-        onLogout={clearTokenAndGoToRoot}
-        setInstanceName={setInstanceName}
-        isPasswordOk={defaultToken !== undefined}
-      />
+    <Fragment>
+      <Menu />
       <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
+        history={history}
         onChange={(e) => {
           const movingOutFromNotification =
             globalNotification && e.url !== globalNotification.to;
@@ -309,7 +294,7 @@ export function InstanceRoutes({
         {/**
          * Admin pages
          */}
-        {admin && (
+        {state.isAdmin && (
           <Route
             path={AdminPaths.list_instances}
             component={InstanceListPage}
@@ -319,12 +304,11 @@ export function InstanceRoutes({
             onUpdate={(id: string): void => {
               route(`/instance/${id}/update`);
             }}
-            setInstanceName={setInstanceName}
             onUnauthorized={LoginPageAccessDenied}
             onLoadError={ServerErrorRedirectTo(InstancePaths.error)}
           />
         )}
-        {admin && (
+        {state.isAdmin && (
           <Route
             path={AdminPaths.new_instance}
             component={InstanceCreatePage}
@@ -334,7 +318,7 @@ export function InstanceRoutes({
             }}
           />
         )}
-        {admin && (
+        {state.isAdmin && (
           <Route
             path={AdminPaths.update_instance}
             component={AdminInstanceUpdatePage}
@@ -374,7 +358,7 @@ export function InstanceRoutes({
             route(`/`);
           }}
           onCancel={() => {
-            route(InstancePaths.order_list)
+            route(InstancePaths.order_list);
           }}
           onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
           onUnauthorized={LoginPageAccessDenied}
@@ -672,7 +656,7 @@ export function InstanceRoutes({
         <Route path="/loading" component={Loading} />
         <Route default component={NotFoundPage} />
       </Router>
-    </InstanceContextProvider>
+    </Fragment>
   );
 }
 
@@ -687,43 +671,35 @@ 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}
-        onLoadError={(error: HttpError<MerchantBackend.ErrorDetail>) => {
+        onLoadError={(error: HttpError<TalerErrorDetail>) => {
           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.hint
+                      : undefined,
+                  type: "ERROR" as const,
+                };
           return (
             <Fragment>
               <NotificationCard notification={notif} />
-              <LoginPage onConfirm={updateLoginStatus} />
+              <LoginPage />
             </Fragment>
           );
         }}
@@ -737,24 +713,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 +750,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..76d38db84 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
@@ -18,11 +18,11 @@
  *
  * @author Sebastian Javier Marchano (sebasjm)
  */
+import { useMerchantApiContext } from "@gnu-taler/web-util/browser";
 import { ComponentChildren, h, VNode } from "preact";
-import { useConfigContext } from "../../context/config.js";
-import { Amount } from "../../declaration.js";
 import { InputWithAddon } from "./InputWithAddon.js";
 import { InputProps } from "./useField.js";
+import { AmountString } from "@gnu-taler/taler-util";
 
 export interface Props<T> extends InputProps<T> {
   expand?: boolean;
@@ -43,7 +43,7 @@ export function InputCurrency<T>({
   children,
   side,
 }: Props<keyof T>): VNode {
-  const config = useConfigContext();
+  const { config } = useMerchantApiContext();
   return (
     <InputWithAddon<T>
       name={name}
@@ -57,7 +57,7 @@ export function InputCurrency<T>({
       addonAfter={addonAfter}
       inputType="number"
       expand={expand}
-      toStr={(v?: Amount) => v?.split(":")[1] || ""}
+      toStr={(v?: AmountString) => v?.split(":")[1] || ""}
       fromStr={(v: string) => (!v ? undefined : `${config.currency}:${v}`)}
       inputExtra={{ min: 0 }}
     >
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..3337e5f57 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
@@ -233,11 +233,11 @@ export function InputPaytoForm<T>({
   }, [str])
 
   // const submit = useCallback((): void => {
-  //   // const accounts: MerchantBackend.BankAccounts.AccountAddDetails[] = 
paytos;
+  //   // const accounts: TalerMerchantApi.AccountAddDetails[] = paytos;
   //   // const alreadyExists =
   //   //   accounts.findIndex((x) => x.payto_uri === paytoURL) !== -1;
   //   // if (!alreadyExists) {
-  //   const newValue: MerchantBackend.BankAccounts.AccountAddDetails = {
+  //   const newValue: TalerMerchantApi.AccountAddDetails = {
   //     payto_uri: paytoURL,
   //   };
   //   if (value.auth) {
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..e47259732 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
@@ -18,16 +18,16 @@
  *
  * @author Sebastian Javier Marchano (sebasjm)
  */
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import { Location, useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h } from "preact";
 import { useLayoutEffect, useState } from "preact/hooks";
-import { MerchantBackend, Timestamp } from "../../declaration.js";
 import { FormErrors, FormProvider } from "./FormProvider.js";
 import { InputDate } from "./InputDate.js";
 import { InputGroup } from "./InputGroup.js";
 import { InputLocation } from "./InputLocation.js";
 import { InputNumber } from "./InputNumber.js";
 import { InputProps, useField } from "./useField.js";
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 
 export interface Props<T> extends InputProps<T> {
   alreadyExist?: boolean;
@@ -39,7 +39,7 @@ export interface Stock {
   current: number;
   lost: number;
   sold: number;
-  address?: MerchantBackend.Location;
+  address?: TalerMerchantApi.Location;
   nextRestock?: Timestamp;
 }
 
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..4392c7659 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
@@ -22,18 +22,18 @@ import { useTranslationContext } from 
"@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { useCallback, useState } from "preact/hooks";
 import * as yup from "yup";
-import { MerchantBackend } from "../../declaration.js";
 import { TaxSchema as schema } from "../../schemas/index.js";
 import { FormErrors, FormProvider } from "./FormProvider.js";
 import { Input } from "./Input.js";
 import { InputGroup } from "./InputGroup.js";
 import { InputProps, useField } from "./useField.js";
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 
 export interface Props<T> extends InputProps<T> {
   isValid?: (e: any) => boolean;
 }
 
-type Entity = MerchantBackend.Tax;
+type Entity = TalerMerchantApi.Tax;
 export function InputTaxes<T>({
   name,
   readonly,
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..cb4442897 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
@@ -19,9 +19,11 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
-import { useBackendContext } from "../../context/backend.js";
+import {
+  useTranslationContext
+} from "@gnu-taler/web-util/browser";
+import { Fragment, VNode, h } from "preact";
+import { useSessionContext } from "../../context/session.js";
 import { Entity } from "../../paths/admin/create/CreatePage.js";
 import { Input } from "../form/Input.js";
 import { InputDuration } from "../form/InputDuration.js";
@@ -40,13 +42,15 @@ export function DefaultInstanceFormFields({
   showId: boolean;
 }): VNode {
   const { i18n } = useTranslationContext();
-  const { url: backendURL } = useBackendContext()
+  const {
+    state: { backendUrl },
+  } = useSessionContext();
   return (
     <Fragment>
       {showId && (
         <InputWithAddon<Entity>
           name="id"
-          addonBefore={`${backendURL}/instances/`}
+          addonBefore={new URL("instances/", backendUrl).href}
           readonly={readonlyId}
           label={i18n.str`Identifier`}
           tooltip={i18n.str`Name of the instance in URLs. The 'default' 
instance is special in that it is used to administer other instances.`}
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..adc47b216 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
@@ -19,43 +19,37 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
-import { useBackendContext } from "../../context/backend.js";
-import { useConfigContext } from "../../context/config.js";
+import {
+  useMerchantApiContext,
+  useTranslationContext,
+} from "@gnu-taler/web-util/browser";
+import { Fragment, VNode, h } from "preact";
+import { useSessionContext } from "../../context/session.js";
 import { useInstanceKYCDetails } from "../../hooks/instance.js";
 import { LangSelector } from "./LangSelector.js";
 
-const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : 
undefined;
+// const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : 
undefined;
 const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : undefined;
 
 interface Props {
-  onLogout: () => void;
-  onShowSettings: () => void;
   mobile?: boolean;
-  instance: string;
-  admin?: boolean;
-  mimic?: boolean;
-  isPasswordOk: boolean;
 }
 
-export function Sidebar({
-  mobile,
-  instance,
-  onShowSettings,
-  onLogout,
-  admin,
-  mimic,
-  isPasswordOk
-}: Props): VNode {
-  const config = useConfigContext();
-  const { url: backendURL } = useBackendContext()
+export function Sidebar({ mobile }: Props): VNode {
   const { i18n } = useTranslationContext();
   const kycStatus = useInstanceKYCDetails();
   const needKYC = kycStatus.ok && kycStatus.data.type === "redirect";
+  const { state, logOut } = useSessionContext();
+  const isLoggedIn = state.status === "loggedIn";
+  const hasToken = isLoggedIn && state.token !== undefined;
+  const backendURL = state.backendUrl;
+  const { config } = useMerchantApiContext();
 
   return (
-    <aside class="aside is-placed-left is-expanded" style={{ overflowY: 
"scroll" }}>
+    <aside
+      class="aside is-placed-left is-expanded"
+      style={{ overflowY: "scroll" }}
+    >
       {mobile && (
         <div
           class="footer"
@@ -80,7 +74,7 @@ export function Sidebar({
         </div>
       </div>
       <div class="menu is-menu-main">
-        {instance ? (
+        {isLoggedIn ? (
           <Fragment>
             <ul class="menu-list">
               <li>
@@ -196,8 +190,11 @@ export function Sidebar({
         </p>
         <ul class="menu-list">
           <li>
-            <a class="has-icon is-state-info is-hoverable"
-              onClick={(): void => onShowSettings()}
+            <a
+              class="has-icon is-state-info is-hoverable"
+              onClick={(e): void => {
+                e.preventDefault();
+              }}
             >
               <span class="icon">
                 <i class="mdi mdi-newspaper" />
@@ -222,12 +219,10 @@ export function Sidebar({
               <span style={{ width: "3rem" }} class="icon">
                 ID
               </span>
-              <span class="menu-item-label">
-                {!instance ? "default" : instance}
-              </span>
+              <span class="menu-item-label">{state.instance}</span>
             </div>
           </li>
-          {admin && !mimic && (
+          {state.isAdmin && (
             <Fragment>
               <p class="menu-label">
                 <i18n.Translate>Instances</i18n.Translate>
@@ -254,11 +249,14 @@ export function Sidebar({
               </li>
             </Fragment>
           )}
-          {isPasswordOk ?
+          {hasToken ? (
             <li>
               <a
                 class="has-icon is-state-info is-hoverable"
-                onClick={(): void => onLogout()}
+                onClick={(e): void => {
+                  logOut();
+                  e.preventDefault();
+                }}
               >
                 <span class="icon">
                   <i class="mdi mdi-logout default" />
@@ -267,8 +265,8 @@ export function Sidebar({
                   <i18n.Translate>Log out</i18n.Translate>
                 </span>
               </a>
-            </li> : undefined
-          }
+            </li>
+          ) : undefined}
         </ul>
       </div>
     </aside>
diff --git a/packages/merchant-backoffice-ui/src/components/menu/index.tsx 
b/packages/merchant-backoffice-ui/src/components/menu/index.tsx
index 7bb7c0c00..aa955db4e 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,10 +17,12 @@
 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 "../../Routing.js";
 import { Notification } from "../../utils/types.js";
 import { NavigationBar } from "./NavigationBar.js";
 import { Sidebar } from "./SideBar.js";
+import { useSessionContext } from "../../context/session.js";
+import { useNavigationContext } from "@gnu-taler/web-util/browser";
 
 function getInstanceTitle(path: string, id: string): string {
   switch (path) {
@@ -77,16 +79,7 @@ function getAdminTitle(path: string, instance: string) {
   return getInstanceTitle(path, instance);
 }
 
-interface MenuProps {
-  title?: string;
-  path: string;
-  instance: string;
-  admin?: boolean;
-  onLogout?: () => void;
-  onShowSettings: () => void;
-  setInstanceName: (s: string) => void;
-  isPasswordOk: boolean;
-}
+interface MenuProps {}
 
 function WithTitle({
   title,
@@ -101,25 +94,18 @@ function WithTitle({
   return <Fragment>{children}</Fragment>;
 }
 
-export function Menu({
-  onLogout,
-  onShowSettings,
-  title,
-  instance,
-  path,
-  admin,
-  setInstanceName,
-  isPasswordOk
-}: MenuProps): VNode {
+export function Menu(_p: MenuProps): VNode {
   const [mobileOpen, setMobileOpen] = useState(false);
 
-  const titleWithSubtitle = title
-    ? title
-    : !admin
-      ? getInstanceTitle(path, instance)
-      : getAdminTitle(path, instance);
-  const adminInstance = instance === "default";
-  const mimic = admin && !adminInstance;
+  const { state, deImpersonate } = useSessionContext();
+  const { path } = useNavigationContext();
+
+  const titleWithSubtitle = !state.isAdmin
+    ? getInstanceTitle(path, state.instance)
+    : getAdminTitle(path, state.instance);
+
+  const isLoggedIn =state.status === "loggedIn";
+
   return (
     <WithTitle title={titleWithSubtitle}>
       <div
@@ -131,32 +117,29 @@ export function Menu({
           title={titleWithSubtitle}
         />
 
-        {onLogout && (
-          <Sidebar
-            onShowSettings={onShowSettings}
-            onLogout={onLogout}
-            admin={admin}
-            mimic={mimic}
-            instance={instance}
-            mobile={mobileOpen}
-            isPasswordOk={isPasswordOk}
-          />
+        {isLoggedIn && (
+          <Sidebar mobile={mobileOpen} />
         )}
 
-        {mimic && (
-          <nav class="level" style={{
-            zIndex: 100,
-            position: "fixed",
-            width: "50%",
-            marginLeft: "20%"
-          }}>
+        {state.status !== "loggedOut" && state.impersonate !== undefined && (
+          <nav
+            class="level"
+            style={{
+              zIndex: 100,
+              position: "fixed",
+              width: "50%",
+              marginLeft: "20%",
+            }}
+          >
             <div class="level-item has-text-centered has-background-warning">
               <p class="is-size-5">
-                You are viewing the instance <b>&quot;{instance}&quot;</b>.{" 
"}
+                You are viewing the instance 
<b>&quot;{state.instance}&quot;</b>
+                .{" "}
                 <a
                   href="#/instances"
                   onClick={(e) => {
-                    setInstanceName("default");
+                    deImpersonate();
+                    e.preventDefault();
                   }}
                 >
                   go back
@@ -238,17 +221,15 @@ export function NotConnectedAppMenu({
   );
 }
 
-export function NotYetReadyAppMenu({
-  onLogout,
-  onShowSettings,
-  title,
-  isPasswordOk
-}: NotYetReadyAppMenuProps): VNode {
+export function NotYetReadyAppMenu({ title }: NotYetReadyAppMenuProps): VNode {
   const [mobileOpen, setMobileOpen] = useState(false);
+  const { state } = useSessionContext();
 
   useEffect(() => {
     document.title = `Taler Backoffice: ${title}`;
   }, [title]);
+  
+  const isLoggedIn = state.status === "loggedIn";
 
   return (
     <div
@@ -259,9 +240,7 @@ export function NotYetReadyAppMenu({
         onMobileMenu={() => setMobileOpen(!mobileOpen)}
         title={title}
       />
-      {onLogout && (
-        <Sidebar onShowSettings={onShowSettings} onLogout={onLogout} 
instance="" mobile={mobileOpen} isPasswordOk={isPasswordOk} />
-      )}
+      {isLoggedIn && <Sidebar mobile={mobileOpen} />}
     </div>
   );
 }
diff --git a/packages/merchant-backoffice-ui/src/components/modal/index.tsx 
b/packages/merchant-backoffice-ui/src/components/modal/index.tsx
index 8372c84cc..1335d0f77 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
@@ -22,11 +22,11 @@
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { ComponentChildren, Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
-import { useInstanceContext } from "../../context/instance.js";
 import { DEFAULT_REQUEST_TIMEOUT } from "../../utils/constants.js";
 import { Spinner } from "../exception/loading.js";
 import { FormProvider } from "../form/FormProvider.js";
 import { Input } from "../form/Input.js";
+import { useSessionContext } from "../../context/session.js";
 
 interface Props {
   active?: boolean;
@@ -298,8 +298,8 @@ export function UpdateTokenModal({
     new_token: !form.new_token
       ? i18n.str`cannot be empty`
       : form.new_token === form.old_token
-      ? i18n.str`cannot be the same as the old token`
-      : undefined,
+        ? i18n.str`cannot be the same as the old token`
+        : undefined,
     repeat_token:
       form.new_token !== form.repeat_token
         ? i18n.str`is not the same`
@@ -310,9 +310,9 @@ export function UpdateTokenModal({
     (k) => (errors as any)[k] !== undefined,
   );
 
-  const instance = useInstanceContext();
+  const { state } = useSessionContext();
 
-  const text = i18n.str`You are updating the access token from instance with 
id ${instance.id}`;
+  const text = i18n.str`You are updating the access token from instance with 
id ${state.instance}`;
 
   return (
     <ClearConfirmModal
@@ -374,8 +374,8 @@ export function SetTokenNewInstanceModal({
     new_token: !form.new_token
       ? i18n.str`cannot be empty`
       : form.new_token === form.old_token
-      ? i18n.str`cannot be the same as the old access token`
-      : undefined,
+        ? i18n.str`cannot be the same as the old access token`
+        : undefined,
     repeat_token:
       form.new_token !== form.repeat_token
         ? i18n.str`is not the same`
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..52ac2a1fe 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
@@ -16,24 +16,24 @@
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { useState } from "preact/hooks";
-import { MerchantBackend, WithId } from "../../declaration.js";
 import { ProductMap } from "../../paths/instance/orders/create/CreatePage.js";
 import { FormErrors, FormProvider } from "../form/FormProvider.js";
 import { InputNumber } from "../form/InputNumber.js";
 import { InputSearchOnList } from "../form/InputSearchOnList.js";
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 
 type Form = {
-  product: MerchantBackend.Products.ProductDetail & WithId;
+  product: TalerMerchantApi.ProductDetail & WithId;
   quantity: number;
 };
 
 interface Props {
   currentProducts: ProductMap;
   onAddProduct: (
-    product: MerchantBackend.Products.ProductDetail & WithId,
+    product: TalerMerchantApi.ProductDetail & WithId,
     quantity: number,
   ) => void;
-  inventory: (MerchantBackend.Products.ProductDetail & WithId)[];
+  inventory: (TalerMerchantApi.ProductDetail & WithId)[];
 }
 
 export function InventoryProductForm({
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/NonInventoryProductForm.tsx
 
b/packages/merchant-backoffice-ui/src/components/product/NonInventoryProductForm.tsx
index c6d280f94..a127999fc 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
@@ -13,11 +13,11 @@
  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 { AmountString, TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { useCallback, useEffect, useState } from "preact/hooks";
 import * as yup from "yup";
-import { MerchantBackend } from "../../declaration.js";
 import { useListener } from "../../hooks/listener.js";
 import { NonInventoryProductSchema as schema } from "../../schemas/index.js";
 import { FormErrors, FormProvider } from "../form/FormProvider.js";
@@ -27,7 +27,7 @@ import { InputImage } from "../form/InputImage.js";
 import { InputNumber } from "../form/InputNumber.js";
 import { InputTaxes } from "../form/InputTaxes.js";
 
-type Entity = MerchantBackend.Product;
+type Entity = TalerMerchantApi.Product;
 
 interface Props {
   onAddProduct: (p: Entity) => Promise<void>;
@@ -46,7 +46,7 @@ export function NonInventoryProductFrom({
   }, [isEditing]);
 
   const [submitForm, addFormSubmitter] = useListener<
-    Partial<MerchantBackend.Product> | undefined
+    Partial<TalerMerchantApi.Product> | undefined
   >((result) => {
     if (result) {
       setShowCreateProduct(false);
@@ -55,7 +55,7 @@ export function NonInventoryProductFrom({
         taxes: result.taxes || [],
         description: result.description || "",
         image: result.image || "",
-        price: result.price || "",
+        price: (result.price || "") as AmountString,
         unit: result.unit || "",
       });
     }
@@ -136,7 +136,7 @@ interface NonInventoryProduct {
   unit: string;
   price: string;
   image: string;
-  taxes: MerchantBackend.Tax[];
+  taxes: TalerMerchantApi.Tax[];
 }
 
 export function ProductForm({ onSubscribe, initial }: ProductProps): VNode {
@@ -144,7 +144,7 @@ export function ProductForm({ onSubscribe, initial }: 
ProductProps): VNode {
     taxes: [],
     ...initial,
   });
-  let errors: FormErrors<Entity> = {};
+  let errors: FormErrors<NonInventoryProduct> = {};
   try {
     schema.validateSync(value, { abortEarly: false });
   } catch (err) {
@@ -159,7 +159,7 @@ export function ProductForm({ onSubscribe, initial }: 
ProductProps): VNode {
   }
 
   const submit = useCallback((): Entity | undefined => {
-    return value as MerchantBackend.Product;
+    return value as TalerMerchantApi.Product;
   }, [value]);
 
   const hasErrors = Object.keys(errors).some(
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx 
b/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx
index e91e8c876..468e5f635 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
@@ -19,12 +19,13 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import {
+  useTranslationContext
+} from "@gnu-taler/web-util/browser";
 import { h } from "preact";
 import { useCallback, useEffect, useState } from "preact/hooks";
 import * as yup from "yup";
-import { useBackendContext } from "../../context/backend.js";
-import { MerchantBackend } from "../../declaration.js";
+import { useSessionContext } from "../../context/session.js";
 import {
   ProductCreateSchema as createSchema,
   ProductUpdateSchema as updateSchema,
@@ -37,8 +38,9 @@ import { InputNumber } from "../form/InputNumber.js";
 import { InputStock, Stock } from "../form/InputStock.js";
 import { InputTaxes } from "../form/InputTaxes.js";
 import { InputWithAddon } from "../form/InputWithAddon.js";
+import { AmountString, TalerMerchantApi } from "@gnu-taler/taler-util";
 
-type Entity = MerchantBackend.Products.ProductDetail & { product_id: string };
+type Entity = TalerMerchantApi.ProductDetail & { product_id: string };
 
 interface Props {
   onSubscribe: (c?: () => Entity | undefined) => void;
@@ -52,18 +54,18 @@ export function ProductForm({ onSubscribe, initial, 
alreadyExist }: Props) {
     description_i18n: {},
     taxes: [],
     next_restock: { t_s: "never" },
-    price: ":0",
+    price: ":0" as AmountString,
     ...initial,
     stock:
       !initial || initial.total_stock === -1
         ? undefined
         : {
-          current: initial.total_stock || 0,
-          lost: initial.total_lost || 0,
-          sold: initial.total_sold || 0,
-          address: initial.address,
-          nextRestock: initial.next_restock,
-        },
+            current: initial.total_stock || 0,
+            lost: initial.total_lost || 0,
+            sold: initial.total_sold || 0,
+            address: initial.address,
+            nextRestock: initial.next_restock,
+          },
   });
   let errors: FormErrors<Entity> = {};
 
@@ -105,7 +107,7 @@ export function ProductForm({ onSubscribe, initial, 
alreadyExist }: Props) {
       delete value.minimum_age;
     }
 
-    return value as MerchantBackend.Products.ProductDetail & {
+    return value as TalerMerchantApi.ProductDetail & {
       product_id: string;
     };
   }, [value]);
@@ -114,7 +116,9 @@ export function ProductForm({ onSubscribe, initial, 
alreadyExist }: Props) {
     onSubscribe(hasErrors ? undefined : submit);
   }, [submit, hasErrors]);
 
-  const { url: backendURL } = useBackendContext()
+  const {
+    state: { backendUrl },
+  } = useSessionContext();
   const { i18n } = useTranslationContext();
 
   return (
@@ -128,7 +132,7 @@ export function ProductForm({ onSubscribe, initial, 
alreadyExist }: Props) {
         {alreadyExist ? undefined : (
           <InputWithAddon<Entity>
             name="product_id"
-            addonBefore={`${backendURL}/product/`}
+            addonBefore={new URL("product/", backendUrl).href}
             label={i18n.str`ID`}
             tooltip={i18n.str`product identification to use in URLs (for 
internal use only)`}
           />
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/ProductList.tsx 
b/packages/merchant-backoffice-ui/src/components/product/ProductList.tsx
index 25751dd96..4fff66fd7 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
@@ -13,18 +13,17 @@
  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 { Amounts } from "@gnu-taler/taler-util";
+import { Amounts, TalerMerchantApi } from "@gnu-taler/taler-util";
 import { h, VNode } from "preact";
 import emptyImage from "../../assets/empty.png";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { MerchantBackend } from "../../declaration.js";
 
 interface Props {
-  list: MerchantBackend.Product[];
+  list: TalerMerchantApi.Product[];
   actions?: {
     name: string;
     tooltip: string;
-    handler: (d: MerchantBackend.Product, index: number) => void;
+    handler: (d: TalerMerchantApi.Product, index: number) => void;
   }[];
 }
 export function ProductList({ list, actions = [] }: Props): VNode {
@@ -60,7 +59,7 @@ export function ProductList({ list, actions = [] }: Props): 
VNode {
               : Amounts.stringify(
                   Amounts.mult(
                     Amounts.parseOrThrow(entry.price),
-                    entry.quantity,
+                    entry.quantity ?? 0
                   ).amount,
                 );
 
diff --git a/packages/merchant-backoffice-ui/src/context/backend.test.ts 
b/packages/merchant-backoffice-ui/src/context/backend.test.ts
deleted file mode 100644
index 359859819..000000000
--- a/packages/merchant-backoffice-ui/src/context/backend.test.ts
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import * as tests from "@gnu-taler/web-util/testing";
-import { ComponentChildren, h, VNode } from "preact";
-import { AccessToken, MerchantBackend } from "../declaration.js";
-import {
-  useAdminAPI,
-  useInstanceAPI,
-  useManagementAPI,
-} from "../hooks/instance.js";
-import { expect } from "chai";
-import { ApiMockEnvironment } from "../hooks/testing.js";
-import {
-  API_CREATE_INSTANCE,
-  API_NEW_LOGIN,
-  API_UPDATE_CURRENT_INSTANCE_AUTH,
-  API_UPDATE_INSTANCE_AUTH_BY_ID,
-} from "../hooks/urls.js";
-
-interface TestingContextProps {
-  children?: ComponentChildren;
-}
-
-describe("backend context api ", () => {
-  it("should use new token after updating the instance token in the settings 
as user", async () => {
-    const env = new ApiMockEnvironment();
-
-    const hookBehavior = await tests.hookBehaveLikeThis(
-      () => {
-        const instance = useInstanceAPI();
-        const management = useManagementAPI("default");
-        const admin = useAdminAPI();
-
-        return { instance, management, admin };
-      },
-      {},
-      [
-        ({ instance, management, admin }) => {
-          env.addRequestExpectation(API_UPDATE_INSTANCE_AUTH_BY_ID("default"), 
{
-            request: {
-              method: "token",
-              token: "another_token",
-            },
-            response: {
-              name: "instance_name",
-            } as MerchantBackend.Instances.QueryInstancesResponse,
-          });
-          env.addRequestExpectation(API_NEW_LOGIN, {
-            auth: "another_token",
-            request: {
-              scope: "write",
-              duration: {
-                "d_us": "forever",
-              },
-              refreshable: true,
-            },
-            
-          });
-
-          management.setNewAccessToken(undefined,"another_token" as 
AccessToken);
-        },
-        ({ instance, management, admin }) => {
-          expect(env.assertJustExpectedRequestWereMade()).deep.eq({
-            result: "ok",
-          });
-
-          env.addRequestExpectation(API_CREATE_INSTANCE, {
-            // auth: "another_token",
-            request: {
-              id: "new_instance_id",
-            } as MerchantBackend.Instances.InstanceConfigurationMessage,
-          });
-
-          admin.createInstance({
-            id: "new_instance_id",
-          } as MerchantBackend.Instances.InstanceConfigurationMessage);
-        },
-      ],
-      env.buildTestingContext(),
-    );
-
-    expect(hookBehavior).deep.eq({ result: "ok" });
-    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" });
-  });
-
-  it("should use new token after updating the instance token in the settings 
as admin", async () => {
-    const env = new ApiMockEnvironment();
-
-    const hookBehavior = await tests.hookBehaveLikeThis(
-      () => {
-        const instance = useInstanceAPI();
-        const management = useManagementAPI("default");
-        const admin = useAdminAPI();
-
-        return { instance, management, admin };
-      },
-      {},
-      [
-        ({ instance, management, admin }) => {
-          env.addRequestExpectation(API_UPDATE_CURRENT_INSTANCE_AUTH, {
-            request: {
-              method: "token",
-              token: "another_token",
-            },
-            response: {
-              name: "instance_name",
-            } as MerchantBackend.Instances.QueryInstancesResponse,
-          });
-          env.addRequestExpectation(API_NEW_LOGIN, {
-            auth: "another_token",
-            request: {
-              scope: "write",
-              duration: {
-                "d_us": "forever",
-              },
-              refreshable: true,
-            },            
-          });
-          instance.setNewAccessToken(undefined, "another_token" as 
AccessToken);
-        },
-        ({ instance, management, admin }) => {
-          expect(env.assertJustExpectedRequestWereMade()).deep.eq({
-            result: "ok",
-          });
-
-          env.addRequestExpectation(API_CREATE_INSTANCE, {
-            // auth: "another_token",
-            request: {
-              id: "new_instance_id",
-            } as MerchantBackend.Instances.InstanceConfigurationMessage,
-          });
-
-          admin.createInstance({
-            id: "new_instance_id",
-          } as MerchantBackend.Instances.InstanceConfigurationMessage);
-        },
-      ],
-      env.buildTestingContext(),
-    );
-
-    expect(hookBehavior).deep.eq({ result: "ok" });
-    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" });
-  });
-});
diff --git a/packages/merchant-backoffice-ui/src/context/backend.ts 
b/packages/merchant-backoffice-ui/src/context/backend.ts
deleted file mode 100644
index 6f2fd2aff..000000000
--- a/packages/merchant-backoffice-ui/src/context/backend.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { useMemoryStorage } from "@gnu-taler/web-util/browser";
-import { createContext, h, VNode } from "preact";
-import { useContext } from "preact/hooks";
-import { LoginToken } from "../declaration.js";
-import { useBackendDefaultToken, useBackendURL } from "../hooks/index.js";
-
-interface BackendContextType {
-  url: string,
-  alreadyTriedLogin: boolean;
-  token?: LoginToken;
-  updateToken: (token: LoginToken | undefined) => void;
-}
-
-const BackendContext = createContext<BackendContextType>({
-  url: "",
-  alreadyTriedLogin: false,
-  token: undefined,
-  updateToken: () => null,
-});
-
-function useBackendContextState(
-  defaultUrl?: string,
-): BackendContextType {
-  const [url] = useBackendURL(defaultUrl);
-  const [token, updateToken] = useBackendDefaultToken();
-
-  return {
-    url,
-    token,
-    alreadyTriedLogin: token !== undefined,
-    updateToken,
-  };
-}
-
-export const BackendContextProvider = ({
-  children,
-  defaultUrl,
-}: {
-  children: any;
-  defaultUrl?: string;
-}): VNode => {
-  const value = useBackendContextState(defaultUrl);
-
-  return h(BackendContext.Provider, { value, children });
-};
-
-export 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
deleted file mode 100644
index 9fe655301..000000000
--- a/packages/merchant-backoffice-ui/src/context/config.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { createContext } from "preact";
-import { useContext } from "preact/hooks";
-import { MerchantBackend } from "../declaration.js";
-
-const Context = createContext<MerchantBackend.VersionResponse>(null!);
-
-export const ConfigContextProvider = Context.Provider;
-export const useConfigContext = (): MerchantBackend.VersionResponse => 
useContext(Context);
diff --git a/packages/merchant-backoffice-ui/src/context/instance.ts 
b/packages/merchant-backoffice-ui/src/context/instance.ts
index 3c6cc2b63..9b67f7170 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
@@ -21,7 +21,6 @@
 
 import { createContext } from "preact";
 import { useContext } from "preact/hooks";
-import { LoginToken } from "../declaration.js";
 
 interface Type {
   id: string;
@@ -32,5 +31,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/session.ts 
b/packages/merchant-backoffice-ui/src/context/session.ts
new file mode 100644
index 000000000..83f3f113a
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/context/session.ts
@@ -0,0 +1,252 @@
+/*
+ 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,
+  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;
+
+interface LoggedIn {
+  status: "loggedIn";
+  backendUrl: string;
+  isAdmin: boolean;
+  instance: string;
+  token: AccessToken | undefined;
+  impersonate: Impersonate | undefined;
+}
+interface Impersonate {
+  originalInstance: string;
+  originalToken: AccessToken | undefined;
+  originalBackendUrl: string;
+}
+interface Expired {
+  status: "expired";
+  backendUrl: string;
+  isAdmin: boolean;
+  instance: string;
+  impersonate: Impersonate | undefined;
+}
+interface LoggedOut {
+  status: "loggedOut";
+  backendUrl: string;
+  instance: string;
+  isAdmin: boolean;
+}
+
+export const codecForSessionStateLoggedIn = (): Codec<LoggedIn> =>
+  buildCodecForObject<LoggedIn>()
+    .property("status", codecForConstString("loggedIn"))
+    .property("backendUrl", codecForString())
+    .property("instance", codecForString())
+    .property("impersonate", codecOptional(codecForImpresonate()))
+    .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("backendUrl", codecForString())
+    .property("instance", codecForString())
+    .property("impersonate", codecOptional(codecForImpresonate()))
+    .property("isAdmin", codecForBoolean())
+    .build("SessionState.Expired");
+
+export const codecForSessionStateLoggedOut = (): Codec<LoggedOut> =>
+  buildCodecForObject<LoggedOut>()
+    .property("status", codecForConstString("loggedOut"))
+    .property("backendUrl", codecForString())
+    .property("instance", codecForString())
+    .property("isAdmin", codecForBoolean())
+    .build("SessionState.LoggedOut");
+
+export const codecForImpresonate = (): Codec<Impersonate> =>
+  buildCodecForObject<Impersonate>()
+    .property("originalInstance", codecForString())
+    .property(
+      "originalToken",
+      codecOptional(codecForString() as Codec<AccessToken>),
+    )
+    .property("originalBackendUrl", codecForString())
+    .build("SessionState.Impersonate");
+
+export const codecForSessionState = (): Codec<SessionState> =>
+  buildCodecForUnion<SessionState>()
+    .discriminateOn("status")
+    .alternative("loggedIn", codecForSessionStateLoggedIn())
+    .alternative("loggedOut", codecForSessionStateLoggedOut())
+    .alternative("expired", codecForSessionStateExpired())
+    .build("SessionState");
+
+function inferInstanceName(url: URL) {
+  const match = INSTANCE_ID_LOOKUP.exec(url.href);
+  return !match || !match[1] ? DEFAULT_ADMIN_USERNAME : match[1];
+}
+
+export const defaultState = (url: URL): SessionState => {
+  const instance = inferInstanceName(url);
+  return {
+    status: "loggedIn",
+    instance,
+    backendUrl: url.href,
+    isAdmin: instance === DEFAULT_ADMIN_USERNAME,
+    token: undefined,
+    impersonate: undefined,
+  };
+};
+
+export interface SessionStateHandler {
+  state: SessionState;
+  /**
+   * from every state to logout state
+   */
+  logOut(): void;
+  /**
+   * from impersonate to loggedIn
+   */
+  deImpersonate(): void;
+  /**
+   * from non-loggedOut state to expired
+   */
+  expired(): void;
+  /**
+   * from any to loggedIn
+   * @param info
+   */
+  logIn(info: { token?: AccessToken }): void;
+  /**
+   * from loggedIn to impersonate
+   * @param info
+   */
+  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 useSessionContext(): SessionStateHandler {
+  const { url } = useMerchantApiContext();
+
+  const { value: state, update } = useLocalStorage(
+    SESSION_STATE_KEY,
+    defaultState(url),
+  );
+
+  return {
+    state,
+    logOut() {
+      const instance = inferInstanceName(url);
+      const nextState: SessionState = {
+        status: "loggedOut",
+        backendUrl: url.href,
+        instance,
+        isAdmin: instance === DEFAULT_ADMIN_USERNAME,
+      };
+      update(nextState);
+    },
+    deImpersonate() {
+      if (state.status === "loggedOut" || state.status === "expired") {
+        // can't impersonate if not loggedin
+        return;
+      }
+      if (state.impersonate === undefined) {
+        return;
+      }
+      const nextState: SessionState = {
+        status: "loggedIn",
+        backendUrl: state.impersonate.originalBackendUrl,
+        isAdmin: state.impersonate.originalInstance === DEFAULT_ADMIN_USERNAME,
+        instance: state.impersonate.originalInstance,
+        token: state.impersonate.originalToken,
+        impersonate: undefined,
+      };
+      update(nextState);
+    },
+    impersonate(info) {
+      if (state.status === "loggedOut" || state.status === "expired") {
+        // can't impersonate if not loggedin
+        return;
+      }
+      const nextState: SessionState = {
+        status: "loggedIn",
+        backendUrl: new URL(`instances/${info.instance}`, state.backendUrl)
+          .href,
+        isAdmin: info.instance === DEFAULT_ADMIN_USERNAME,
+        instance: info.instance,
+        token: info.token,
+        impersonate: {
+          originalBackendUrl: state.backendUrl,
+          originalToken: state.token,
+          originalInstance: state.instance,
+        },
+      };
+      update(nextState);
+    },
+    expired() {
+      if (state.status === "loggedOut") return;
+
+      const nextState: SessionState = {
+        ...state,
+        status: "expired",
+      };
+      update(nextState);
+    },
+    logIn(info) {
+      // admin is defined by the username
+      const nextState: SessionState = {
+        impersonate: undefined,
+        ...state,
+        status: "loggedIn",
+        token: info.token,
+      };
+      update(nextState);
+      cleanAllCache();
+    },
+  };
+}
+
+function cleanAllCache(): void {
+  mutate(() => true, undefined, { revalidate: false });
+}
diff --git a/packages/bank-ui/src/context/settings.ts 
b/packages/merchant-backoffice-ui/src/context/settings.ts
similarity index 85%
copy from packages/bank-ui/src/context/settings.ts
copy to packages/merchant-backoffice-ui/src/context/settings.ts
index 053fcbd12..8bd1506d6 100644
--- a/packages/bank-ui/src/context/settings.ts
+++ b/packages/merchant-backoffice-ui/src/context/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
@@ -16,16 +16,16 @@
 
 import { ComponentChildren, createContext, h, VNode } from "preact";
 import { useContext } from "preact/hooks";
-import { BankUiSettings } from "../settings.js";
+import { MerchantUiSettings } from "../settings.js";
 
 /**
  *
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-export type Type = BankUiSettings;
+export type Type = MerchantUiSettings;
 
-const initial: BankUiSettings = {};
+const initial: MerchantUiSettings = {};
 const Context = createContext<Type>(initial);
 
 export const useSettingsContext = (): Type => useContext(Context);
@@ -34,7 +34,7 @@ export const SettingsProvider = ({
   children,
   value,
 }: {
-  value: BankUiSettings;
+  value: MerchantUiSettings;
   children: ComponentChildren;
 }): VNode => {
   return h(Context.Provider, {
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..93fecd9c4 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
@@ -28,7 +28,7 @@ type ImageDataUrl = string;
 type MerchantUserType = "business" | "individual";
 
 
-export interface WithId {
+interface WithId {
   id: string;
 }
 
@@ -117,11 +117,8 @@ interface LoginToken {
 // token used to get loginToken
 // must forget after used
 declare const __ac_token: unique symbol;
-type AccessToken = string & {
-  [__ac_token]: true;
-};
 
-export namespace ExchangeBackend {
+namespace dead_ExchangeBackend2 {
   interface WireResponse {
     // Master public key of the exchange, must match the key returned in /keys.
     master_public_key: EddsaPublicKey;
@@ -156,7 +153,7 @@ export namespace ExchangeBackend {
     sig: EddsaSignature;
   }
 }
-export namespace MerchantBackend {
+namespace dead_MerchantBackend2 {
   interface ErrorDetail {
     // Numeric error code unique to the condition.
     // The other arguments are specific to the error value reported here.
@@ -347,7 +344,7 @@ export namespace MerchantBackend {
     // Free-form address lines, should not exceed 7 elements.
     address_lines?: string[];
   }
-  namespace Instances {
+  namespace dead_Instances2 {
     //POST /private/instances/$INSTANCE/auth
     interface InstanceAuthConfigurationMessage {
       // Type of authentication.
@@ -573,7 +570,7 @@ export namespace MerchantBackend {
     }
   }
 
-  namespace KYC {
+  namespace dead_KYC {
     //GET /private/instances/$INSTANCE/kyc
     interface AccountKycRedirects {
       // Array of pending KYCs.
@@ -615,7 +612,7 @@ export namespace MerchantBackend {
 
   }
 
-  namespace BankAccounts {
+  namespace dead_BankAccounts {
 
     interface AccountAddDetails {
 
@@ -709,7 +706,7 @@ export namespace MerchantBackend {
 
   }
 
-  namespace Products {
+  namespace dead_Products {
     // POST /private/products
     interface ProductAddDetail {
       // product ID to use.
@@ -868,7 +865,7 @@ export namespace MerchantBackend {
     //   DELETE /private/products/$PRODUCT_ID
   }
 
-  namespace Orders {
+  namespace dead_Orders {
     type MerchantOrderStatusResponse =
       | CheckPaymentPaidResponse
       | CheckPaymentClaimedResponse
@@ -1150,7 +1147,7 @@ export namespace MerchantBackend {
     }
   }
 
-  namespace Rewards {
+  namespace dead_Rewards {
     // GET /private/reserves
     interface RewardReserveStatus {
       // Array of all known reserves (possibly empty!)
@@ -1306,7 +1303,7 @@ export namespace MerchantBackend {
     }
   }
 
-  namespace Transfers {
+  namespace dead_Transfers {
     interface TransferList {
       // list of all the transfers that fit the filter that we know
       transfers: TransferDetails[];
@@ -1358,7 +1355,7 @@ export namespace MerchantBackend {
     }
   }
 
-  namespace OTP {
+  namespace dead_OTP {
     interface OtpDeviceAddDetails {
       // Device ID to use.
       otp_device_id: string;
@@ -1415,7 +1412,7 @@ export namespace MerchantBackend {
 
 
   }
-  namespace Template {
+  namespace dead_Template {
     interface TemplateAddDetails {
       // Template ID to use.
       template_id: string;
@@ -1497,7 +1494,7 @@ export namespace MerchantBackend {
     }
   }
 
-  namespace Webhooks {
+  namespace dead_Webhooks {
     type MerchantWebhookType = "pay" | "refund";
     interface WebhookAddDetails {
       // Webhook ID to use.
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..8eb9b4cf2 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
@@ -19,22 +19,22 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { AbsoluteTime, HttpStatusCode } from "@gnu-taler/taler-util";
 import {
-  ErrorType,
+  TalerErrorDetail,
+  TalerMerchantApi
+} from "@gnu-taler/taler-util";
+import {
+  EmptyObject,
   HttpError,
   HttpResponse,
   HttpResponseOk,
   RequestError,
   RequestOptions,
-  useApiContext,
+  useApiContext
 } from "@gnu-taler/web-util/browser";
 import { useCallback, useEffect, useState } from "preact/hooks";
 import { useSWRConfig } from "swr";
-import { useBackendContext } from "../context/backend.js";
-import { useInstanceContext } from "../context/instance.js";
-import { AccessToken, LoginToken, MerchantBackend, Timestamp } from 
"../declaration.js";
-
+import { useSessionContext } from "../context/session.js";
 
 export function useMatchMutate(): (
   re?: RegExp,
@@ -49,37 +49,41 @@ export function useMatchMutate(): (
   }
 
   return function matchRegexMutate(re?: RegExp) {
-    return mutate((key) => {
-      // evict if no key or regex === all
-      if (!key || !re) return true
-      // match string
-      if (typeof key === 'string' && re.test(key)) return true
-      // record or object have the path at [0]
-      if (typeof key === 'object' && re.test(key[0])) return true
-      //key didn't match regex
-      return false
-    }, undefined, {
-      revalidate: true,
-    });
+    return mutate(
+      (key) => {
+        // evict if no key or regex === all
+        if (!key || !re) return true;
+        // match string
+        if (typeof key === "string" && re.test(key)) return true;
+        // record or object have the path at [0]
+        if (typeof key === "object" && re.test(key[0])) return true;
+        //key didn't match regex
+        return false;
+      },
+      undefined,
+      {
+        revalidate: true,
+      },
+    );
   };
 }
 
 export function useBackendInstancesTestForAdmin(): HttpResponse<
-  MerchantBackend.Instances.InstancesResponse,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.InstancesResponse,
+  TalerErrorDetail
 > {
   const { request } = useBackendBaseRequest();
 
-  type Type = MerchantBackend.Instances.InstancesResponse;
+  type Type = TalerMerchantApi.InstancesResponse;
 
   const [result, setResult] = useState<
-    HttpResponse<Type, MerchantBackend.ErrorDetail>
+    HttpResponse<Type, TalerErrorDetail>
   >({ loading: true });
 
   useEffect(() => {
     request<Type>(`/management/instances`)
       .then((data) => setResult(data))
-      .catch((error: RequestError<MerchantBackend.ErrorDetail>) =>
+      .catch((error: RequestError<TalerErrorDetail>) =>
         setResult(error.cause),
       );
   }, [request]);
@@ -91,36 +95,42 @@ const CHECK_CONFIG_INTERVAL_OK = 5 * 60 * 1000;
 const CHECK_CONFIG_INTERVAL_FAIL = 2 * 1000;
 
 export function useBackendConfig(): HttpResponse<
-  MerchantBackend.VersionResponse | undefined,
-  RequestError<MerchantBackend.ErrorDetail>
+  TalerMerchantApi.VersionResponse | undefined,
+  RequestError<TalerErrorDetail>
 > {
   const { request } = useBackendBaseRequest();
 
-  type Type = MerchantBackend.VersionResponse;
-  type State = { data: HttpResponse<Type, 
RequestError<MerchantBackend.ErrorDetail>>, timer: number }
-  const [result, setResult] = useState<State>({ data: { loading: true }, 
timer: 0 });
+  type Type = TalerMerchantApi.VersionResponse;
+  type State = {
+    data: HttpResponse<Type, RequestError<TalerErrorDetail>>;
+    timer: number;
+  };
+  const [result, setResult] = useState<State>({
+    data: { loading: true },
+    timer: 0,
+  });
 
   useEffect(() => {
     if (result.timer) {
-      clearTimeout(result.timer)
+      clearTimeout(result.timer);
     }
     function tryConfig(): void {
       request<Type>(`/config`)
         .then((data) => {
           const timer: any = setTimeout(() => {
-            tryConfig()
-          }, CHECK_CONFIG_INTERVAL_OK)
-          setResult({ data, timer })
+            tryConfig();
+          }, CHECK_CONFIG_INTERVAL_OK);
+          setResult({ data, timer });
         })
         .catch((error) => {
           const timer: any = setTimeout(() => {
-            tryConfig()
-          }, CHECK_CONFIG_INTERVAL_FAIL)
-          const data = error.cause
-          setResult({ data, timer })
+            tryConfig();
+          }, CHECK_CONFIG_INTERVAL_FAIL);
+          const data = error.cause;
+          setResult({ data, timer });
         });
     }
-    tryConfig()
+    tryConfig();
   }, [request]);
 
   return result.data;
@@ -134,29 +144,29 @@ interface useBackendInstanceRequestType {
   fetcher: <T>(endpoint: string) => Promise<HttpResponseOk<T>>;
   multiFetcher: <T>(params: [url: string[]]) => Promise<HttpResponseOk<T>[]>;
   orderFetcher: <T>(
-    params: [endpoint: string,
+    params: [
+      endpoint: string,
       paid?: YesOrNo,
       refunded?: YesOrNo,
       wired?: YesOrNo,
       searchDate?: Date,
-      delta?: number,]
+      delta?: number,
+    ],
   ) => Promise<HttpResponseOk<T>>;
   transferFetcher: <T>(
-    params: [endpoint: string,
+    params: [
+      endpoint: string,
       payto_uri?: string,
       verified?: string,
       position?: string,
-      delta?: number,]
+      delta?: number,
+    ],
   ) => Promise<HttpResponseOk<T>>;
   templateFetcher: <T>(
-    params: [endpoint: string,
-      position?: string,
-      delta?: number]
+    params: [endpoint: string, position?: string, delta?: number],
   ) => Promise<HttpResponseOk<T>>;
   webhookFetcher: <T>(
-    params: [endpoint: string,
-      position?: string,
-      delta?: number]
+    params: [endpoint: string, position?: string, delta?: number],
   ) => Promise<HttpResponseOk<T>>;
 }
 interface useBackendBaseRequestType {
@@ -167,87 +177,16 @@ interface useBackendBaseRequestType {
 }
 
 type YesOrNo = "yes" | "no";
-type LoginResult = {
-  valid: true;
-  token: string;
-  expiration: Timestamp;
-} | {
-  valid: false;
-  cause: HttpError<{}>;
-}
-
-export function useCredentialsChecker() {
-  const { request } = useApiContext();
-  //check against instance details endpoint
-  //while merchant backend doesn't have a login endpoint
-  async function requestNewLoginToken(
-    baseUrl: string,
-    token: AccessToken,
-  ): Promise<LoginResult> {
-    const data: MerchantBackend.Instances.LoginTokenRequest = {
-      scope: "write",
-      duration: {
-        d_us: "forever"
-      },
-      refreshable: true,
+type LoginResult =
+  | {
+      valid: true;
+      token: string;
+      expiration: Timestamp;
     }
-    try {
-      const response = await 
request<MerchantBackend.Instances.LoginTokenSuccessResponse>(baseUrl, 
`/private/token`, {
-        method: "POST",
-        token,
-        data
-      });
-      return { valid: true, token: response.data.token, expiration: 
response.data.expiration };
-    } catch (error) {
-      if (error instanceof RequestError) {
-        return { valid: false, cause: error.cause };
-      }
-
-      return {
-        valid: false, cause: {
-          type: ErrorType.UNEXPECTED,
-          loading: false,
-          info: {
-            hasToken: true,
-            status: 0,
-            options: {},
-            url: `/private/token`,
-            payload: {}
-          },
-          exception: error,
-          message: (error instanceof Error ? error.message : "unpexepected 
error")
-        }
-      };
-    }
-  };
-
-  async function refreshLoginToken(
-    baseUrl: string,
-    token: LoginToken
-  ): Promise<LoginResult> {
-
-    if 
(AbsoluteTime.isExpired(AbsoluteTime.fromProtocolTimestamp(token.expiration))) {
-      return {
-        valid: false, cause: {
-          type: ErrorType.CLIENT,
-          status: HttpStatusCode.Unauthorized,
-          message: "login token expired, login again.",
-          info: {
-            hasToken: true,
-            status: 401,
-            options: {},
-            url: `/private/token`,
-            payload: {}
-          },
-          payload: {}
-        },
-      }
-    }
-
-    return requestNewLoginToken(baseUrl, token.token as AccessToken)
-  }
-  return { requestNewLoginToken, refreshLoginToken }
-}
+  | {
+      valid: false;
+      cause: HttpError<EmptyObject>;
+    };
 
 /**
  *
@@ -255,37 +194,36 @@ export function useCredentialsChecker() {
  * @returns request handler to
  */
 export function useBackendBaseRequest(): useBackendBaseRequestType {
-  const { url: backend, token: loginToken } = useBackendContext();
   const { request: requestHandler } = useApiContext();
-  const token = loginToken?.token;
+  const { state } = useSessionContext();
+  const token = state.status === "loggedIn" ? state.token : undefined;
+  const baseUrl = state.backendUrl;
 
   const request = useCallback(
     function requestImpl<T>(
       endpoint: string,
       options: RequestOptions = {},
     ): Promise<HttpResponseOk<T>> {
-      return requestHandler<T>(backend, endpoint, { ...options, token 
}).then(res => {
-        return res
-      }).catch(err => {
-        throw err
-      });
+      return requestHandler<T>(baseUrl, endpoint, { ...options, token })
+        .then((res) => {
+          return res;
+        })
+        .catch((err) => {
+          throw err;
+        });
     },
-    [backend, token],
+    [baseUrl, token],
   );
 
   return { request };
 }
 
 export function useBackendInstanceRequest(): useBackendInstanceRequestType {
-  const { url: rootBackendUrl, token: rootToken } = useBackendContext();
-  const { token: instanceToken, admin } = useInstanceContext();
   const { request: requestHandler } = useApiContext();
 
-  const { baseUrl, token: loginToken } = !admin
-    ? { baseUrl: rootBackendUrl, token: rootToken }
-    : { baseUrl: rootBackendUrl, token: instanceToken };
-
-  const token = loginToken?.token;
+  const { state } = useSessionContext();
+  const token = state.status === "loggedIn" ? state.token : undefined;
+  const baseUrl = state.backendUrl;
 
   const request = useCallback(
     function requestImpl<T>(
@@ -301,7 +239,7 @@ export function useBackendInstanceRequest(): 
useBackendInstanceRequestType {
     function multiFetcherImpl<T>(
       args: [endpoints: string[]],
     ): Promise<HttpResponseOk<T>[]> {
-      const [endpoints] = args
+      const [endpoints] = args;
       return Promise.all(
         endpoints.map((endpoint) =>
           requestHandler<T>(baseUrl, endpoint, { token }),
@@ -320,18 +258,22 @@ export function useBackendInstanceRequest(): 
useBackendInstanceRequestType {
 
   const orderFetcher = useCallback(
     function orderFetcherImpl<T>(
-      args: [endpoint: string,
+      args: [
+        endpoint: string,
         paid?: YesOrNo,
         refunded?: YesOrNo,
         wired?: YesOrNo,
         searchDate?: Date,
-        delta?: number,]
+        delta?: number,
+      ],
     ): Promise<HttpResponseOk<T>> {
-      const [endpoint, paid, refunded, wired, searchDate, delta] = args
+      const [endpoint, paid, refunded, wired, searchDate, delta] = args;
       const date_s =
         delta && delta < 0 && searchDate
           ? Math.floor(searchDate.getTime() / 1000) + 1
-          : searchDate !== undefined ? Math.floor(searchDate.getTime() / 1000) 
: undefined;
+          : searchDate !== undefined
+            ? Math.floor(searchDate.getTime() / 1000)
+            : undefined;
       const params: any = {};
       if (paid !== undefined) params.paid = paid;
       if (delta !== undefined) params.delta = delta;
@@ -339,12 +281,12 @@ export function useBackendInstanceRequest(): 
useBackendInstanceRequestType {
       if (wired !== undefined) params.wired = wired;
       if (date_s !== undefined) params.date_s = date_s;
       if (delta === 0) {
-        //in this case we can already assume the response 
+        //in this case we can already assume the response
         //and avoid network
         return Promise.resolve({
           ok: true,
           data: { orders: [] } as T,
-        })
+        });
       }
       return requestHandler<T>(baseUrl, endpoint, { params, token });
     },
@@ -353,23 +295,25 @@ export function useBackendInstanceRequest(): 
useBackendInstanceRequestType {
 
   const transferFetcher = useCallback(
     function transferFetcherImpl<T>(
-      args: [endpoint: string,
+      args: [
+        endpoint: string,
         payto_uri?: string,
         verified?: string,
         position?: string,
-        delta?: number,]
+        delta?: number,
+      ],
     ): Promise<HttpResponseOk<T>> {
-      const [endpoint, payto_uri, verified, position, delta] = args
+      const [endpoint, payto_uri, verified, position, delta] = args;
       const params: any = {};
       if (payto_uri !== undefined) params.payto_uri = payto_uri;
       if (verified !== undefined) params.verified = verified;
       if (delta === 0) {
-        //in this case we can already assume the response 
+        //in this case we can already assume the response
         //and avoid network
         return Promise.resolve({
           ok: true,
           data: { transfers: [] } as T,
-        })
+        });
       }
       if (delta !== undefined) {
         params.limit = delta;
@@ -383,19 +327,17 @@ export function useBackendInstanceRequest(): 
useBackendInstanceRequestType {
 
   const templateFetcher = useCallback(
     function templateFetcherImpl<T>(
-      args: [endpoint: string,
-        position?: string,
-        delta?: number,]
+      args: [endpoint: string, position?: string, delta?: number],
     ): Promise<HttpResponseOk<T>> {
-      const [endpoint, position, delta] = args
+      const [endpoint, position, delta] = args;
       const params: any = {};
       if (delta === 0) {
-        //in this case we can already assume the response 
+        //in this case we can already assume the response
         //and avoid network
         return Promise.resolve({
           ok: true,
           data: { templates: [] } as T,
-        })
+        });
       }
       if (delta !== undefined) {
         params.limit = delta;
@@ -409,19 +351,17 @@ export function useBackendInstanceRequest(): 
useBackendInstanceRequestType {
 
   const webhookFetcher = useCallback(
     function webhookFetcherImpl<T>(
-      args: [endpoint: string,
-        position?: string,
-        delta?: number,]
+      args: [endpoint: string, position?: string, delta?: number],
     ): Promise<HttpResponseOk<T>> {
-      const [endpoint, position, delta] = args
+      const [endpoint, position, delta] = args;
       const params: any = {};
       if (delta === 0) {
-        //in this case we can already assume the response 
+        //in this case we can already assume the response
         //and avoid network
         return Promise.resolve({
           ok: true,
           data: { webhooks: [] } as T,
-        })
+        });
       }
       if (delta !== undefined) {
         params.limit = delta;
diff --git a/packages/merchant-backoffice-ui/src/hooks/bank.ts 
b/packages/merchant-backoffice-ui/src/hooks/bank.ts
index 5d5785442..3cf9c7846 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
@@ -20,15 +20,15 @@ import {
   RequestError,
 } from "@gnu-taler/web-util/browser";
 import { useEffect, useState } from "preact/hooks";
-import { MerchantBackend } from "../declaration.js";
 import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils/constants.js";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
 import _useSWR, { SWRHook, mutate } from "swr";
+import { TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
 const useSWR = _useSWR as unknown as SWRHook;
 
-// const MOCKED_ACCOUNTS: Record<string, 
MerchantBackend.BankAccounts.AccountAddDetails> = {
+// const MOCKED_ACCOUNTS: Record<string, TalerMerchantApi.AccountAddDetails> = 
{
 //   "hwire1": {
 //     h_wire: "hwire1",
 //     payto_uri: "payto://fake/iban/123",
@@ -46,7 +46,7 @@ export function useBankAccountAPI(): BankAccountAPI {
   const { request } = useBackendInstanceRequest();
 
   const createBankAccount = async (
-    data: MerchantBackend.BankAccounts.AccountAddDetails,
+    data: TalerMerchantApi.AccountAddDetails,
   ): Promise<HttpResponseOk<void>> => {
     // MOCKED_ACCOUNTS[data.h_wire] = data
     // return Promise.resolve({ ok: true, data: undefined });
@@ -60,7 +60,7 @@ export function useBankAccountAPI(): BankAccountAPI {
 
   const updateBankAccount = async (
     h_wire: string,
-    data: MerchantBackend.BankAccounts.AccountPatchDetails,
+    data: TalerMerchantApi.AccountPatchDetails,
   ): Promise<HttpResponseOk<void>> => {
     // MOCKED_ACCOUNTS[h_wire].credit_facade_credentials = 
data.credit_facade_credentials
     // MOCKED_ACCOUNTS[h_wire].credit_facade_url = data.credit_facade_url
@@ -94,11 +94,11 @@ export function useBankAccountAPI(): BankAccountAPI {
 
 export interface BankAccountAPI {
   createBankAccount: (
-    data: MerchantBackend.BankAccounts.AccountAddDetails,
+    data: TalerMerchantApi.AccountAddDetails,
   ) => Promise<HttpResponseOk<void>>;
   updateBankAccount: (
     id: string,
-    data: MerchantBackend.BankAccounts.AccountPatchDetails,
+    data: TalerMerchantApi.AccountPatchDetails,
   ) => Promise<HttpResponseOk<void>>;
   deleteBankAccount: (id: string) => Promise<HttpResponseOk<void>>;
 }
@@ -114,8 +114,8 @@ export function useInstanceBankAccounts(
   args?: InstanceBankAccountFilter,
   updatePosition?: (id: string) => void,
 ): HttpResponsePaginated<
-  MerchantBackend.BankAccounts.AccountsSummaryResponse,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.AccountsSummaryResponse,
+  TalerErrorDetail
 > {
 
   const { fetcher } = useBackendInstanceRequest();
@@ -128,14 +128,14 @@ export function useInstanceBankAccounts(
     error: afterError,
     isValidating: loadingAfter,
   } = useSWR<
-    HttpResponseOk<MerchantBackend.BankAccounts.AccountsSummaryResponse>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.AccountsSummaryResponse>,
+    RequestError<TalerErrorDetail>
   >([`/private/accounts`], fetcher);
 
   const [lastAfter, setLastAfter] = useState<
     HttpResponse<
-      MerchantBackend.BankAccounts.AccountsSummaryResponse,
-      MerchantBackend.ErrorDetail
+      TalerMerchantApi.AccountsSummaryResponse,
+      TalerErrorDetail
     >
   >({ loading: true });
   useEffect(() => {
@@ -179,8 +179,8 @@ export function useInstanceBankAccounts(
 export function useBankAccountDetails(
   h_wire: string,
 ): HttpResponse<
-  MerchantBackend.BankAccounts.BankAccountEntry,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.BankAccountEntry,
+  TalerErrorDetail
 > {
   // return {
   //   ok: true,
@@ -192,8 +192,8 @@ export function useBankAccountDetails(
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
-    HttpResponseOk<MerchantBackend.BankAccounts.BankAccountEntry>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.BankAccountEntry>,
+    RequestError<TalerErrorDetail>
   >([`/private/accounts/${h_wire}`], fetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
diff --git a/packages/merchant-backoffice-ui/src/hooks/index.ts 
b/packages/merchant-backoffice-ui/src/hooks/index.ts
deleted file mode 100644
index 9c194fdee..000000000
--- a/packages/merchant-backoffice-ui/src/hooks/index.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { 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 { LoginToken } from "../declaration.js";
-import { ValueOrFunction } from "../utils/types.js";
-import { useMatchMutate } from "./backend.js";
-
-const calculateRootPath = () => {
-  const rootPath =
-    typeof window !== undefined
-      ? window.location.origin + window.location.pathname
-      : "/";
-
-  /**
-   * 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 rootPath.replace("/webui/", "");
-};
-
-const loginTokenCodec = buildCodecForObject<LoginToken>()
-  .property("token", codecForString())
-  .property("expiration", codecForTimestamp)
-  .build("loginToken")
-const TOKENS_KEY = buildStorageKey("merchant-token", 
codecForMap(loginTokenCodec));
-
-
-export function useBackendURL(
-  url?: string,
-): [string, StateUpdater<string>] {
-  const [value, setter] = useSimpleLocalStorage(
-    "merchant-base-url",
-    url || calculateRootPath(),
-  );
-
-  const checkedSetter = (v: ValueOrFunction<string>) => {
-    return setter((p) => (v instanceof Function ? v(p ?? "") : 
v).replace(/\/$/, ""));
-  };
-
-  return [value!, checkedSetter];
-}
-
-export function useBackendDefaultToken(
-): [LoginToken | undefined, ((d: LoginToken | undefined) => void)] {
-  const { update: setToken, value: tokenMap, reset } = 
useLocalStorage(TOKENS_KEY, {})
-
-  // const tokenOfDefaultInstance = tokenMap["default"]
-  // const clearCache = useMatchMutate()
-  // useEffect(() => {
-  //   clearCache()
-  // }, [tokenOfDefaultInstance])
-
-  function updateToken(
-    value: (LoginToken | undefined)
-  ): void {
-    if (value === undefined) {
-      reset()
-    } else {
-      const res = { ...tokenMap, "default": value }
-      setToken(res)
-    }
-  }
-  return [tokenMap["default"], updateToken];
-}
-
-export function useBackendInstanceToken(
-  id: string,
-): [LoginToken | undefined, ((d: LoginToken | undefined) => void)] {
-  const { update: setToken, value: tokenMap, reset } = 
useLocalStorage(TOKENS_KEY, {})
-  const [defaultToken, defaultSetToken] = useBackendDefaultToken();
-
-  // instance named 'default' use the default token
-  if (id === "default") {
-    return [defaultToken, defaultSetToken];
-  }
-  function updateToken(
-    value: (LoginToken | undefined)
-  ): void {
-    if (value === undefined) {
-      reset()
-    } else {
-      const res = { ...tokenMap, [id]: value }
-      setToken(res)
-    }
-  }
-
-  return [tokenMap[id], updateToken];
-}
-
-export function useLang(initial?: string): [string, StateUpdater<string>] {
-  const browserLang =
-    typeof window !== "undefined"
-      ? navigator.language || (navigator as any).userLanguage
-      : undefined;
-  const defaultLang = (browserLang || initial || "en").substring(0, 2);
-  return useSimpleLocalStorage("lang-preference", defaultLang) as [string, 
StateUpdater<string>];
-}
-
-export function useSimpleLocalStorage(
-  key: string,
-  initialValue?: string,
-): [string | undefined, StateUpdater<string | undefined>] {
-  const [storedValue, setStoredValue] = useState<string | undefined>(
-    (): string | undefined => {
-      return typeof window !== "undefined"
-        ? window.localStorage.getItem(key) || initialValue
-        : initialValue;
-    },
-  );
-
-  const setValue = (
-    value?: string | ((val?: string) => string | undefined),
-  ) => {
-    setStoredValue((p) => {
-      const toStore = value instanceof Function ? value(p) : value;
-      if (typeof window !== "undefined") {
-        if (!toStore) {
-          window.localStorage.removeItem(key);
-        } else {
-          window.localStorage.setItem(key, toStore);
-        }
-      }
-      return toStore;
-    });
-  };
-
-  return [storedValue, setValue];
-}
diff --git a/packages/merchant-backoffice-ui/src/hooks/instance.test.ts 
b/packages/merchant-backoffice-ui/src/hooks/instance.test.ts
index ee1576764..35147d988 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
@@ -19,9 +19,9 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { AccessToken, TalerMerchantApi } from "@gnu-taler/taler-util";
 import * as tests from "@gnu-taler/web-util/testing";
 import { expect } from "chai";
-import { AccessToken, MerchantBackend } from "../declaration.js";
 import {
   useAdminAPI,
   useBackendInstances,
@@ -35,7 +35,6 @@ import {
   API_DELETE_INSTANCE,
   API_GET_CURRENT_INSTANCE,
   API_LIST_INSTANCES,
-  API_NEW_LOGIN,
   API_UPDATE_CURRENT_INSTANCE,
   API_UPDATE_CURRENT_INSTANCE_AUTH,
   API_UPDATE_INSTANCE_BY_ID,
@@ -48,7 +47,7 @@ describe("instance api interaction with details", () => {
     env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
       response: {
         name: "instance_name",
-      } as MerchantBackend.Instances.QueryInstancesResponse,
+      } as TalerMerchantApi.QueryInstancesResponse,
     });
 
     const hookBehavior = await tests.hookBehaveLikeThis(
@@ -76,16 +75,16 @@ describe("instance api interaction with details", () => {
           env.addRequestExpectation(API_UPDATE_CURRENT_INSTANCE, {
             request: {
               name: "other_name",
-            } as MerchantBackend.Instances.InstanceReconfigurationMessage,
+            } as TalerMerchantApi.InstanceReconfigurationMessage,
           });
           env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
             response: {
               name: "other_name",
-            } as MerchantBackend.Instances.QueryInstancesResponse,
+            } as TalerMerchantApi.QueryInstancesResponse,
           });
           api.updateInstance({
             name: "other_name",
-          } as MerchantBackend.Instances.InstanceReconfigurationMessage);
+          } as TalerMerchantApi.InstanceReconfigurationMessage);
         },
         ({ query, api }) => {
           expect(env.assertJustExpectedRequestWereMade()).deep.eq({
@@ -109,15 +108,15 @@ describe("instance api interaction with details", () => {
   it("should evict cache when setting the instance's token", async () => {
     const env = new ApiMockEnvironment();
 
-    env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
-      response: {
-        name: "instance_name",
-        auth: {
-          method: "token",
-          // token: "not-secret",
-        },
-      } as MerchantBackend.Instances.QueryInstancesResponse,
-    });
+    // env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
+    //   response: {
+    //     name: "instance_name",
+    //     auth: {
+    //       method: "token",
+    //       // token: "not-secret",
+    //     },
+    //   } as TalerMerchantApi.QueryInstancesResponse,
+    // });
 
     const hookBehavior = await tests.hookBehaveLikeThis(
       () => {
@@ -147,28 +146,28 @@ describe("instance api interaction with details", () => {
             request: {
               method: "token",
               token: "secret",
-            } as MerchantBackend.Instances.InstanceAuthConfigurationMessage,
-          });
-          env.addRequestExpectation(API_NEW_LOGIN, {
-            auth: "secret",
-            request: {
-              scope: "write",
-              duration: {
-                "d_us": "forever",
-              },
-              refreshable: true,
-            },            
-          });
+            } as TalerMerchantApi.InstanceAuthConfigurationMessage,
+          });
+          // env.addRequestExpectation(API_NEW_LOGIN, {
+          //   auth: "secret",
+          //   request: {
+          //     scope: "write",
+          //     duration: {
+          //       "d_us": "forever",
+          //     },
+          //     refreshable: true,
+          //   },            
+          // });
           env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
             response: {
               name: "instance_name",
               auth: {
-                method: "token",
+                type: "token",
                 // token: "secret",
               },
-            } as MerchantBackend.Instances.QueryInstancesResponse,
+            } as TalerMerchantApi.QueryInstancesResponse,
           });
-          api.setNewAccessToken(undefined, "secret" as AccessToken);
+          // api.setNewAccessToken(undefined, "secret" as AccessToken);
         },
         ({ query, api }) => {
           expect(env.assertJustExpectedRequestWereMade()).deep.eq({
@@ -199,10 +198,10 @@ describe("instance api interaction with details", () => {
       response: {
         name: "instance_name",
         auth: {
-          method: "token",
+          type: "token",
           // token: "not-secret",
         },
-      } as MerchantBackend.Instances.QueryInstancesResponse,
+      } as TalerMerchantApi.QueryInstancesResponse,
     });
 
     const hookBehavior = await tests.hookBehaveLikeThis(
@@ -233,15 +232,15 @@ describe("instance api interaction with details", () => {
           env.addRequestExpectation(API_UPDATE_CURRENT_INSTANCE_AUTH, {
             request: {
               method: "external",
-            } as MerchantBackend.Instances.InstanceAuthConfigurationMessage,
+            } as TalerMerchantApi.InstanceAuthConfigurationMessage,
           });
           env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
             response: {
               name: "instance_name",
               auth: {
-                method: "external",
+                type: "external",
               },
-            } as MerchantBackend.Instances.QueryInstancesResponse,
+            } as TalerMerchantApi.QueryInstancesResponse,
           });
 
           api.clearAccessToken(undefined);
@@ -331,7 +330,7 @@ describe("instance admin api interaction with listing", () 
=> {
         instances: [
           {
             name: "instance_name",
-          } as MerchantBackend.Instances.Instance,
+          } as TalerMerchantApi.Instance,
         ],
       },
     });
@@ -365,24 +364,24 @@ describe("instance admin api interaction with listing", 
() => {
           env.addRequestExpectation(API_CREATE_INSTANCE, {
             request: {
               name: "other_name",
-            } as MerchantBackend.Instances.InstanceConfigurationMessage,
+            } as TalerMerchantApi.InstanceConfigurationMessage,
           });
           env.addRequestExpectation(API_LIST_INSTANCES, {
             response: {
               instances: [
                 {
                   name: "instance_name",
-                } as MerchantBackend.Instances.Instance,
+                } as TalerMerchantApi.Instance,
                 {
                   name: "other_name",
-                } as MerchantBackend.Instances.Instance,
+                } as TalerMerchantApi.Instance,
               ],
             },
           });
 
           api.createInstance({
             name: "other_name",
-          } as MerchantBackend.Instances.InstanceConfigurationMessage);
+          } as TalerMerchantApi.InstanceConfigurationMessage);
         },
         ({ query, api }) => {
           expect(env.assertJustExpectedRequestWereMade()).deep.eq({
@@ -418,11 +417,11 @@ describe("instance admin api interaction with listing", 
() => {
           {
             id: "default",
             name: "instance_name",
-          } as MerchantBackend.Instances.Instance,
+          } as TalerMerchantApi.Instance,
           {
             id: "the_id",
             name: "second_instance",
-          } as MerchantBackend.Instances.Instance,
+          } as TalerMerchantApi.Instance,
         ],
       },
     });
@@ -465,7 +464,7 @@ describe("instance admin api interaction with listing", () 
=> {
                 {
                   id: "default",
                   name: "instance_name",
-                } as MerchantBackend.Instances.Instance,
+                } as TalerMerchantApi.Instance,
               ],
             },
           });
@@ -542,7 +541,7 @@ describe("instance admin api interaction with listing", () 
=> {
     //     instances: [{
     //       id: 'default',
     //       name: 'instance_name'
-    //     } as MerchantBackend.Instances.Instance]
+    //     } as TalerMerchantApi.Instance]
     //   },
     // });
 
@@ -572,11 +571,11 @@ describe("instance admin api interaction with listing", 
() => {
           {
             id: "default",
             name: "instance_name",
-          } as MerchantBackend.Instances.Instance,
+          } as TalerMerchantApi.Instance,
           {
             id: "the_id",
             name: "second_instance",
-          } as MerchantBackend.Instances.Instance,
+          } as TalerMerchantApi.Instance,
         ],
       },
     });
@@ -623,7 +622,7 @@ describe("instance admin api interaction with listing", () 
=> {
                 {
                   id: "default",
                   name: "instance_name",
-                } as MerchantBackend.Instances.Instance,
+                } as TalerMerchantApi.Instance,
               ],
             },
           });
@@ -664,7 +663,7 @@ describe("instance management api interaction with 
listing", () => {
           {
             id: "managed",
             name: "instance_name",
-          } as MerchantBackend.Instances.Instance,
+          } as TalerMerchantApi.Instance,
         ],
       },
     });
@@ -699,7 +698,7 @@ describe("instance management api interaction with 
listing", () => {
           env.addRequestExpectation(API_UPDATE_INSTANCE_BY_ID("managed"), {
             request: {
               name: "other_name",
-            } as MerchantBackend.Instances.InstanceReconfigurationMessage,
+            } as TalerMerchantApi.InstanceReconfigurationMessage,
           });
           env.addRequestExpectation(API_LIST_INSTANCES, {
             response: {
@@ -707,14 +706,14 @@ describe("instance management api interaction with 
listing", () => {
                 {
                   id: "managed",
                   name: "other_name",
-                } as MerchantBackend.Instances.Instance,
+                } as TalerMerchantApi.Instance,
               ],
             },
           });
 
           api.updateInstance({
             name: "other_name",
-          } as MerchantBackend.Instances.InstanceConfigurationMessage);
+          } as TalerMerchantApi.InstanceConfigurationMessage);
         },
         ({ query, api }) => {
           expect(env.assertJustExpectedRequestWereMade()).deep.eq({
diff --git a/packages/merchant-backoffice-ui/src/hooks/instance.ts 
b/packages/merchant-backoffice-ui/src/hooks/instance.ts
index 0677191db..5f17dbf79 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
@@ -16,28 +16,30 @@
 import {
   HttpResponse,
   HttpResponseOk,
-  RequestError,
+  RequestError
 } from "@gnu-taler/web-util/browser";
-import { useBackendContext } from "../context/backend.js";
-import { AccessToken, MerchantBackend } from "../declaration.js";
 import {
   useBackendBaseRequest,
   useBackendInstanceRequest,
-  useCredentialsChecker,
   useMatchMutate,
 } from "./backend.js";
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
+import { AccessToken, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import _useSWR, { SWRHook, useSWRConfig } from "swr";
+import { useSessionContext } from "../context/session.js";
 const useSWR = _useSWR as unknown as SWRHook;
 
 interface InstanceAPI {
   updateInstance: (
-    data: MerchantBackend.Instances.InstanceReconfigurationMessage,
+    data: TalerMerchantApi.InstanceReconfigurationMessage,
   ) => Promise<void>;
   deleteInstance: () => Promise<void>;
   clearAccessToken: (currentToken: AccessToken | undefined) => Promise<void>;
-  setNewAccessToken: (currentToken: AccessToken | undefined, token: 
AccessToken) => Promise<void>;
+  // setNewAccessToken: (
+  //   currentToken: AccessToken | undefined,
+  //   token: AccessToken,
+  // ) => Promise<void>;
 }
 
 export function useAdminAPI(): AdminAPI {
@@ -45,7 +47,7 @@ export function useAdminAPI(): AdminAPI {
   const mutateAll = useMatchMutate();
 
   const createInstance = async (
-    instance: MerchantBackend.Instances.InstanceConfigurationMessage,
+    instance: TalerMerchantApi.InstanceConfigurationMessage,
   ): Promise<void> => {
     await request(`/management/instances`, {
       method: "POST",
@@ -79,7 +81,7 @@ export function useAdminAPI(): AdminAPI {
 
 export interface AdminAPI {
   createInstance: (
-    data: MerchantBackend.Instances.InstanceConfigurationMessage,
+    data: TalerMerchantApi.InstanceConfigurationMessage,
   ) => Promise<void>;
   deleteInstance: (id: string) => Promise<void>;
   purgeInstance: (id: string) => Promise<void>;
@@ -87,13 +89,15 @@ export interface AdminAPI {
 
 export function useManagementAPI(instanceId: string): InstanceAPI {
   const mutateAll = useMatchMutate();
-  const { url: backendURL } = useBackendContext()
-  const { updateToken } = useBackendContext();
+  const {
+    state: { backendUrl },
+    logIn,
+    logOut,
+  } = useSessionContext();
   const { request } = useBackendBaseRequest();
-  const { requestNewLoginToken } = useCredentialsChecker()
 
   const updateInstance = async (
-    instance: MerchantBackend.Instances.InstanceReconfigurationMessage,
+    instance: TalerMerchantApi.InstanceReconfigurationMessage,
   ): Promise<void> => {
     await request(`/management/instances/${instanceId}`, {
       method: "PATCH",
@@ -111,7 +115,9 @@ export function useManagementAPI(instanceId: string): 
InstanceAPI {
     mutateAll(/\/management\/instances/);
   };
 
-  const clearAccessToken = async (currentToken: AccessToken | undefined): 
Promise<void> => {
+  const clearAccessToken = async (
+    currentToken: AccessToken | undefined,
+  ): Promise<void> => {
     await request(`/management/instances/${instanceId}/auth`, {
       method: "POST",
       token: currentToken,
@@ -121,46 +127,58 @@ export function useManagementAPI(instanceId: string): 
InstanceAPI {
     mutateAll(/\/management\/instances/);
   };
 
-  const setNewAccessToken = async (currentToken: AccessToken | undefined, 
newToken: AccessToken): Promise<void> => {
-    await request(`/management/instances/${instanceId}/auth`, {
-      method: "POST",
-      token: currentToken,
-      data: { method: "token", token: newToken },
-    });
-
-    const resp = await requestNewLoginToken(backendURL, newToken)
-    if (resp.valid) {
-      const { token, expiration } = resp
-      updateToken({ token, expiration });
-    } else {
-      updateToken(undefined)
-    }
-
-    mutateAll(/\/management\/instances/);
+  // const setNewAccessToken = async (
+  //   currentToken: AccessToken | undefined,
+  //   newToken: AccessToken,
+  // ): Promise<void> => {
+
+  //   await request(`/management/instances/${instanceId}/auth`, {
+  //     method: "POST",
+  //     token: currentToken,
+  //     data: { method: "token", token: newToken },
+  //   });
+
+  //   const resp = await requestNewLoginToken(backendUrl, newToken);
+  //   if (resp.valid) {
+  //     logIn({ token: resp.token as AccessToken });
+  //   } else {
+  //     logOut();
+  //   }
+
+  //   mutateAll(/\/management\/instances/);
+  // };
+
+  return {
+    updateInstance,
+    deleteInstance,
+    // setNewAccessToken,
+    clearAccessToken,
   };
-
-  return { updateInstance, deleteInstance, setNewAccessToken, clearAccessToken 
};
 }
 
 export function useInstanceAPI(): InstanceAPI {
   const { mutate } = useSWRConfig();
-  const { url: backendURL, updateToken } = useBackendContext()
-
   const {
-    token: adminToken,
-  } = useBackendContext();
+    state: { backendUrl },
+  } = useSessionContext();
+
   const { request } = useBackendInstanceRequest();
-  const { requestNewLoginToken } = useCredentialsChecker()
+  const { state, logIn, logOut } = useSessionContext();
+
+  const adminToken =
+    state.status === "loggedIn" && state.isAdmin ? state.token : undefined;
 
   const updateInstance = async (
-    instance: MerchantBackend.Instances.InstanceReconfigurationMessage,
+    instance: TalerMerchantApi.InstanceReconfigurationMessage,
   ): Promise<void> => {
     await request(`/private/`, {
       method: "PATCH",
       data: instance,
     });
 
-    if (adminToken) mutate(["/private/instances", adminToken, backendURL], 
null);
+    if (adminToken) {
+      mutate(["/private/instances", adminToken, backendUrl], null);
+    }
     mutate([`/private/`], null);
   };
 
@@ -170,11 +188,15 @@ export function useInstanceAPI(): InstanceAPI {
       // token: adminToken,
     });
 
-    if (adminToken) mutate(["/private/instances", adminToken, backendURL], 
null);
+    if (adminToken) {
+      mutate(["/private/instances", adminToken, backendUrl], null);
+    }
     mutate([`/private/`], null);
   };
 
-  const clearAccessToken = async (currentToken: AccessToken | undefined): 
Promise<void> => {
+  const clearAccessToken = async (
+    currentToken: AccessToken | undefined,
+  ): Promise<void> => {
     await request(`/private/auth`, {
       method: "POST",
       token: currentToken,
@@ -184,36 +206,43 @@ export function useInstanceAPI(): InstanceAPI {
     mutate([`/private/`], null);
   };
 
-  const setNewAccessToken = async (currentToken: AccessToken | undefined, 
newToken: AccessToken): Promise<void> => {
-    await request(`/private/auth`, {
-      method: "POST",
-      token: currentToken,
-      data: { method: "token", token: newToken },
-    });
-
-    const resp = await requestNewLoginToken(backendURL, newToken)
-    if (resp.valid) {
-      const { token, expiration } = resp
-      updateToken({ token, expiration });
-    } else {
-      updateToken(undefined)
-    }
-
-    mutate([`/private/`], null);
+  // const setNewAccessToken = async (
+  //   currentToken: AccessToken | undefined,
+  //   newToken: AccessToken,
+  // ): Promise<void> => {
+  //   await request(`/private/auth`, {
+  //     method: "POST",
+  //     token: currentToken,
+  //     data: { method: "token", token: newToken },
+  //   });
+
+  //   const resp = await requestNewLoginToken(backendUrl, newToken);
+  //   if (resp.valid) {
+  //     logIn({ token: resp.token as AccessToken });
+  //   } else {
+  //     logOut();
+  //   }
+
+  //   mutate([`/private/`], null);
+  // };
+
+  return {
+    updateInstance,
+    deleteInstance,
+    // setNewAccessToken,
+    clearAccessToken,
   };
-
-  return { updateInstance, deleteInstance, setNewAccessToken, clearAccessToken 
};
 }
 
 export function useInstanceDetails(): HttpResponse<
-  MerchantBackend.Instances.QueryInstancesResponse,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.QueryInstancesResponse,
+  TalerErrorDetail
 > {
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
-    HttpResponseOk<MerchantBackend.Instances.QueryInstancesResponse>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.QueryInstancesResponse>,
+    RequestError<TalerErrorDetail>
   >([`/private/`], fetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
@@ -234,17 +263,17 @@ export function useInstanceDetails(): HttpResponse<
 
 type KYCStatus =
   | { type: "ok" }
-  | { type: "redirect"; status: MerchantBackend.KYC.AccountKycRedirects };
+  | { type: "redirect"; status: TalerMerchantApi.AccountKycRedirects };
 
 export function useInstanceKYCDetails(): HttpResponse<
   KYCStatus,
-  MerchantBackend.ErrorDetail
+  TalerErrorDetail
 > {
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error } = useSWR<
-    HttpResponseOk<MerchantBackend.KYC.AccountKycRedirects>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.AccountKycRedirects>,
+    RequestError<TalerErrorDetail>
   >([`/private/kyc`], fetcher, {
     refreshInterval: 60 * 1000,
     refreshWhenHidden: false,
@@ -270,14 +299,14 @@ export function useInstanceKYCDetails(): HttpResponse<
 export function useManagedInstanceDetails(
   instanceId: string,
 ): HttpResponse<
-  MerchantBackend.Instances.QueryInstancesResponse,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.QueryInstancesResponse,
+  TalerErrorDetail
 > {
   const { request } = useBackendBaseRequest();
 
   const { data, error, isValidating } = useSWR<
-    HttpResponseOk<MerchantBackend.Instances.QueryInstancesResponse>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.QueryInstancesResponse>,
+    RequestError<TalerErrorDetail>
   >([`/management/instances/${instanceId}`], request, {
     refreshInterval: 0,
     refreshWhenHidden: false,
@@ -296,14 +325,14 @@ export function useManagedInstanceDetails(
 }
 
 export function useBackendInstances(): HttpResponse<
-  MerchantBackend.Instances.InstancesResponse,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.InstancesResponse,
+  TalerErrorDetail
 > {
   const { request } = useBackendBaseRequest();
 
   const { data, error, isValidating } = useSWR<
-    HttpResponseOk<MerchantBackend.Instances.InstancesResponse>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.InstancesResponse>,
+    RequestError<TalerErrorDetail>
   >(["/management/instances"], request);
 
   if (isValidating) return { loading: true, data: data?.data };
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..47d9e5624 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
@@ -20,15 +20,15 @@ import {
   RequestError,
 } from "@gnu-taler/web-util/browser";
 import { useEffect, useState } from "preact/hooks";
-import { MerchantBackend } from "../declaration.js";
 import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils/constants.js";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
+import { TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
 import _useSWR, { SWRHook, mutate } from "swr";
 const useSWR = _useSWR as unknown as SWRHook;
 
-// const MOCKED_ACCOUNTS: Record<string, 
MerchantBackend.BankAccounts.AccountAddDetails> = {
+// const MOCKED_ACCOUNTS: Record<string, TalerMerchantApi.AccountAddDetails> = 
{
 //   "hwire1": {
 //     h_wire: "hwire1",
 //     payto_uri: "payto://fake/iban/123",
@@ -46,7 +46,7 @@ export function useBankAccountAPI(): BankAccountAPI {
   const { request } = useBackendInstanceRequest();
 
   const createBankAccount = async (
-    data: MerchantBackend.BankAccounts.AccountAddDetails,
+    data: TalerMerchantApi.AccountAddDetails,
   ): Promise<HttpResponseOk<void>> => {
     // MOCKED_ACCOUNTS[data.h_wire] = data
     // return Promise.resolve({ ok: true, data: undefined });
@@ -60,7 +60,7 @@ export function useBankAccountAPI(): BankAccountAPI {
 
   const updateBankAccount = async (
     h_wire: string,
-    data: MerchantBackend.BankAccounts.AccountPatchDetails,
+    data: TalerMerchantApi.AccountPatchDetails,
   ): Promise<HttpResponseOk<void>> => {
     // MOCKED_ACCOUNTS[h_wire].credit_facade_credentials = 
data.credit_facade_credentials
     // MOCKED_ACCOUNTS[h_wire].credit_facade_url = data.credit_facade_url
@@ -94,11 +94,11 @@ export function useBankAccountAPI(): BankAccountAPI {
 
 export interface BankAccountAPI {
   createBankAccount: (
-    data: MerchantBackend.BankAccounts.AccountAddDetails,
+    data: TalerMerchantApi.AccountAddDetails,
   ) => Promise<HttpResponseOk<void>>;
   updateBankAccount: (
     id: string,
-    data: MerchantBackend.BankAccounts.AccountPatchDetails,
+    data: TalerMerchantApi.AccountPatchDetails,
   ) => Promise<HttpResponseOk<void>>;
   deleteBankAccount: (id: string) => Promise<HttpResponseOk<void>>;
 }
@@ -114,8 +114,8 @@ export function useInstanceBankAccounts(
   args?: InstanceBankAccountFilter,
   updatePosition?: (id: string) => void,
 ): HttpResponsePaginated<
-  MerchantBackend.BankAccounts.AccountsSummaryResponse,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.AccountsSummaryResponse,
+  TalerErrorDetail
 > {
 
   const { fetcher } = useBackendInstanceRequest();
@@ -128,14 +128,14 @@ export function useInstanceBankAccounts(
     error: afterError,
     isValidating: loadingAfter,
   } = useSWR<
-    HttpResponseOk<MerchantBackend.BankAccounts.AccountsSummaryResponse>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.AccountsSummaryResponse>,
+    RequestError<TalerErrorDetail>
   >([`/private/accounts`], fetcher);
 
   const [lastAfter, setLastAfter] = useState<
     HttpResponse<
-      MerchantBackend.BankAccounts.AccountsSummaryResponse,
-      MerchantBackend.ErrorDetail
+      TalerMerchantApi.AccountsSummaryResponse,
+      TalerErrorDetail
     >
   >({ loading: true });
   useEffect(() => {
@@ -179,8 +179,8 @@ export function useInstanceBankAccounts(
 export function useBankAccountDetails(
   h_wire: string,
 ): HttpResponse<
-  MerchantBackend.BankAccounts.BankAccountEntry,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.BankAccountEntry,
+  TalerErrorDetail
 > {
   // return {
   //   ok: true,
@@ -192,8 +192,8 @@ export function useBankAccountDetails(
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
-    HttpResponseOk<MerchantBackend.BankAccounts.BankAccountEntry>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.BankAccountEntry>,
+    RequestError<TalerErrorDetail>
   >([`/private/accounts/${h_wire}`], fetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
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..0d4199875 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
@@ -19,9 +19,9 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { AmountString, TalerMerchantApi } from "@gnu-taler/taler-util";
 import * as tests from "@gnu-taler/web-util/testing";
 import { expect } from "chai";
-import { MerchantBackend } from "../declaration.js";
 import { useInstanceOrders, useOrderAPI, useOrderDetails } from "./order.js";
 import { ApiMockEnvironment } from "./testing.js";
 import {
@@ -40,7 +40,7 @@ describe("order api interaction with listing", () => {
     env.addRequestExpectation(API_LIST_ORDERS, {
       qparam: { delta: -20, paid: "yes" },
       response: {
-        orders: [{ order_id: "1" }, { order_id: "2" } as 
MerchantBackend.Orders.OrderHistoryEntry],
+        orders: [{ order_id: "1" }, { order_id: "2" } as 
TalerMerchantApi.OrderHistoryEntry],
       },
     });
 
@@ -72,7 +72,8 @@ describe("order api interaction with listing", () => {
 
           env.addRequestExpectation(API_CREATE_ORDER, {
             request: {
-              order: { amount: "ARS:12", summary: "pay me" },
+              order: { amount: "ARS:12" as AmountString, summary: "pay me" },
+              lock_uuids: []
             },
             response: { order_id: "3" },
           });
@@ -112,11 +113,13 @@ describe("order api interaction with listing", () => {
 
     env.addRequestExpectation(API_LIST_ORDERS, {
       qparam: { delta: -20, paid: "yes" },
-      response: { orders: [{
-        order_id: "1",
-        amount: "EUR:12",
-        refundable: true,
-      } as MerchantBackend.Orders.OrderHistoryEntry] },
+      response: {
+        orders: [{
+          order_id: "1",
+          amount: "EUR:12",
+          refundable: true,
+        } as TalerMerchantApi.OrderHistoryEntry]
+      },
     });
 
     const newDate = (d: Date) => {
@@ -160,14 +163,16 @@ describe("order api interaction with listing", () => {
 
           env.addRequestExpectation(API_LIST_ORDERS, {
             qparam: { delta: -20, paid: "yes" },
-            response: { orders: [
-              { order_id: "1", amount: "EUR:12", refundable: false } as any,
-            ] },
+            response: {
+              orders: [
+                { order_id: "1", amount: "EUR:12", refundable: false } as any,
+              ]
+            },
           });
 
           api.refundOrder("1", {
             reason: "double pay",
-            refund: "EUR:1",
+            refund: "EUR:1" as AmountString,
           });
         },
         ({ query, api }) => {
@@ -202,7 +207,7 @@ describe("order api interaction with listing", () => {
     env.addRequestExpectation(API_LIST_ORDERS, {
       qparam: { delta: -20, paid: "yes" },
       response: {
-        orders: [{ order_id: "1" }, { order_id: "2" } as 
MerchantBackend.Orders.OrderHistoryEntry],
+        orders: [{ order_id: "1" }, { order_id: "2" } as 
TalerMerchantApi.OrderHistoryEntry],
       },
     });
 
@@ -271,7 +276,7 @@ describe("order api interaction with details", () => {
       response: {
         summary: "description",
         refund_amount: "EUR:0",
-      } as unknown as MerchantBackend.Orders.CheckPaymentPaidResponse,
+      } as unknown as TalerMerchantApi.CheckPaymentPaidResponse,
     });
 
     const newDate = (d: Date) => {
@@ -311,12 +316,12 @@ describe("order api interaction with details", () => {
             response: {
               summary: "description",
               refund_amount: "EUR:1",
-            } as unknown as MerchantBackend.Orders.CheckPaymentPaidResponse,
+            } as unknown as TalerMerchantApi.CheckPaymentPaidResponse,
           });
 
           api.refundOrder("1", {
             reason: "double pay",
-            refund: "EUR:1",
+            refund: "EUR:1" as AmountString,
           });
         },
         ({ query, api }) => {
@@ -347,7 +352,7 @@ describe("order api interaction with details", () => {
       response: {
         summary: "description",
         refund_amount: "EUR:0",
-      } as unknown as MerchantBackend.Orders.CheckPaymentPaidResponse,
+      } as unknown as TalerMerchantApi.CheckPaymentPaidResponse,
     });
 
     const newDate = (d: Date) => {
@@ -385,7 +390,7 @@ describe("order api interaction with details", () => {
           env.addRequestExpectation(API_GET_ORDER_BY_ID("1"), {
             response: {
               summary: undefined,
-            } as unknown as MerchantBackend.Orders.CheckPaymentPaidResponse,
+            } as unknown as TalerMerchantApi.CheckPaymentPaidResponse,
           });
 
           api.forgetOrder("1", {
diff --git a/packages/merchant-backoffice-ui/src/hooks/order.ts 
b/packages/merchant-backoffice-ui/src/hooks/order.ts
index e7a893f2c..39bc1725b 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
@@ -20,27 +20,27 @@ import {
   RequestError,
 } from "@gnu-taler/web-util/browser";
 import { useEffect, useState } from "preact/hooks";
-import { MerchantBackend } from "../declaration.js";
 import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils/constants.js";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
+import { TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
 import _useSWR, { SWRHook } from "swr";
 const useSWR = _useSWR as unknown as SWRHook;
 
 export interface OrderAPI {
   //FIXME: add OutOfStockResponse on 410
   createOrder: (
-    data: MerchantBackend.Orders.PostOrderRequest,
-  ) => Promise<HttpResponseOk<MerchantBackend.Orders.PostOrderResponse>>;
+    data: TalerMerchantApi.PostOrderRequest,
+  ) => Promise<HttpResponseOk<TalerMerchantApi.PostOrderResponse>>;
   forgetOrder: (
     id: string,
-    data: MerchantBackend.Orders.ForgetRequest,
+    data: TalerMerchantApi.ForgetRequest,
   ) => Promise<HttpResponseOk<void>>;
   refundOrder: (
     id: string,
-    data: MerchantBackend.Orders.RefundRequest,
-  ) => Promise<HttpResponseOk<MerchantBackend.Orders.MerchantRefundResponse>>;
+    data: TalerMerchantApi.RefundRequest,
+  ) => Promise<HttpResponseOk<TalerMerchantApi.MerchantRefundResponse>>;
   deleteOrder: (id: string) => Promise<HttpResponseOk<void>>;
   getPaymentURL: (id: string) => Promise<HttpResponseOk<string>>;
 }
@@ -52,9 +52,9 @@ export function useOrderAPI(): OrderAPI {
   const { request } = useBackendInstanceRequest();
 
   const createOrder = async (
-    data: MerchantBackend.Orders.PostOrderRequest,
-  ): Promise<HttpResponseOk<MerchantBackend.Orders.PostOrderResponse>> => {
-    const res = await request<MerchantBackend.Orders.PostOrderResponse>(
+    data: TalerMerchantApi.PostOrderRequest,
+  ): Promise<HttpResponseOk<TalerMerchantApi.PostOrderResponse>> => {
+    const res = await request<TalerMerchantApi.PostOrderResponse>(
       `/private/orders`,
       {
         method: "POST",
@@ -67,10 +67,10 @@ export function useOrderAPI(): OrderAPI {
   };
   const refundOrder = async (
     orderId: string,
-    data: MerchantBackend.Orders.RefundRequest,
-  ): Promise<HttpResponseOk<MerchantBackend.Orders.MerchantRefundResponse>> => 
{
+    data: TalerMerchantApi.RefundRequest,
+  ): Promise<HttpResponseOk<TalerMerchantApi.MerchantRefundResponse>> => {
     mutateAll(/@"\/private\/orders"@/);
-    const res = request<MerchantBackend.Orders.MerchantRefundResponse>(
+    const res = request<TalerMerchantApi.MerchantRefundResponse>(
       `/private/orders/${orderId}/refund`,
       {
         method: "POST",
@@ -85,7 +85,7 @@ export function useOrderAPI(): OrderAPI {
 
   const forgetOrder = async (
     orderId: string,
-    data: MerchantBackend.Orders.ForgetRequest,
+    data: TalerMerchantApi.ForgetRequest,
   ): Promise<HttpResponseOk<void>> => {
     mutateAll(/@"\/private\/orders"@/);
     const res = request<void>(`/private/orders/${orderId}/forget`, {
@@ -110,7 +110,7 @@ export function useOrderAPI(): OrderAPI {
   const getPaymentURL = async (
     orderId: string,
   ): Promise<HttpResponseOk<string>> => {
-    return request<MerchantBackend.Orders.MerchantOrderStatusResponse>(
+    return request<TalerMerchantApi.MerchantOrderStatusResponse>(
       `/private/orders/${orderId}`,
       {
         method: "GET",
@@ -132,14 +132,14 @@ export function useOrderAPI(): OrderAPI {
 export function useOrderDetails(
   oderId: string,
 ): HttpResponse<
-  MerchantBackend.Orders.MerchantOrderStatusResponse,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.MerchantOrderStatusResponse,
+  TalerErrorDetail
 > {
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
-    HttpResponseOk<MerchantBackend.Orders.MerchantOrderStatusResponse>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.MerchantOrderStatusResponse>,
+    RequestError<TalerErrorDetail>
   >([`/private/orders/${oderId}`], fetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
@@ -165,8 +165,8 @@ export function useInstanceOrders(
   args?: InstanceOrderFilter,
   updateFilter?: (d: Date) => void,
 ): HttpResponsePaginated<
-  MerchantBackend.Orders.OrderHistory,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.OrderHistory,
+  TalerErrorDetail
 > {
   const { orderFetcher } = useBackendInstanceRequest();
 
@@ -187,8 +187,8 @@ export function useInstanceOrders(
     error: beforeError,
     isValidating: loadingBefore,
   } = useSWR<
-    HttpResponseOk<MerchantBackend.Orders.OrderHistory>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.OrderHistory>,
+    RequestError<TalerErrorDetail>
   >(
     [
       `/private/orders`,
@@ -205,8 +205,8 @@ export function useInstanceOrders(
     error: afterError,
     isValidating: loadingAfter,
   } = useSWR<
-    HttpResponseOk<MerchantBackend.Orders.OrderHistory>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.OrderHistory>,
+    RequestError<TalerErrorDetail>
   >(
     [
       `/private/orders`,
@@ -222,14 +222,14 @@ export function useInstanceOrders(
   //this will save last result
   const [lastBefore, setLastBefore] = useState<
     HttpResponse<
-      MerchantBackend.Orders.OrderHistory,
-      MerchantBackend.ErrorDetail
+      TalerMerchantApi.OrderHistory,
+      TalerErrorDetail
     >
   >({ loading: true });
   const [lastAfter, setLastAfter] = useState<
     HttpResponse<
-      MerchantBackend.Orders.OrderHistory,
-      MerchantBackend.ErrorDetail
+      TalerMerchantApi.OrderHistory,
+      TalerErrorDetail
     >
   >({ loading: true });
   useEffect(() => {
diff --git a/packages/merchant-backoffice-ui/src/hooks/otp.ts 
b/packages/merchant-backoffice-ui/src/hooks/otp.ts
index b045e365a..4b45dcf06 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
@@ -20,35 +20,20 @@ import {
   RequestError,
 } from "@gnu-taler/web-util/browser";
 import { useEffect, useState } from "preact/hooks";
-import { MerchantBackend } from "../declaration.js";
 import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils/constants.js";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
+import { TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
 import _useSWR, { SWRHook } from "swr";
 const useSWR = _useSWR as unknown as SWRHook;
 
-const MOCKED_DEVICES: Record<string, MerchantBackend.OTP.OtpDeviceAddDetails> 
= {
-  "1": {
-    otp_device_description: "first device",
-    otp_algorithm: 1,
-    otp_device_id: "1",
-    otp_key: "123",
-  },
-  "2": {
-    otp_device_description: "second device",
-    otp_algorithm: 0,
-    otp_device_id: "2",
-    otp_key: "456",
-  }
-}
-
 export function useOtpDeviceAPI(): OtpDeviceAPI {
   const mutateAll = useMatchMutate();
   const { request } = useBackendInstanceRequest();
 
   const createOtpDevice = async (
-    data: MerchantBackend.OTP.OtpDeviceAddDetails,
+    data: TalerMerchantApi.OtpDeviceAddDetails,
   ): Promise<HttpResponseOk<void>> => {
     // MOCKED_DEVICES[data.otp_device_id] = data
     // return Promise.resolve({ ok: true, data: undefined });
@@ -62,7 +47,7 @@ export function useOtpDeviceAPI(): OtpDeviceAPI {
 
   const updateOtpDevice = async (
     deviceId: string,
-    data: MerchantBackend.OTP.OtpDevicePatchDetails,
+    data: TalerMerchantApi.OtpDevicePatchDetails,
   ): Promise<HttpResponseOk<void>> => {
     // MOCKED_DEVICES[deviceId].otp_algorithm = data.otp_algorithm
     // MOCKED_DEVICES[deviceId].otp_ctr = data.otp_ctr
@@ -98,11 +83,11 @@ export function useOtpDeviceAPI(): OtpDeviceAPI {
 
 export interface OtpDeviceAPI {
   createOtpDevice: (
-    data: MerchantBackend.OTP.OtpDeviceAddDetails,
+    data: TalerMerchantApi.OtpDeviceAddDetails,
   ) => Promise<HttpResponseOk<void>>;
   updateOtpDevice: (
     id: string,
-    data: MerchantBackend.OTP.OtpDevicePatchDetails,
+    data: TalerMerchantApi.OtpDevicePatchDetails,
   ) => Promise<HttpResponseOk<void>>;
   deleteOtpDevice: (id: string) => Promise<HttpResponseOk<void>>;
 }
@@ -114,8 +99,8 @@ export function useInstanceOtpDevices(
   args?: InstanceOtpDeviceFilter,
   updatePosition?: (id: string) => void,
 ): HttpResponsePaginated<
-  MerchantBackend.OTP.OtpDeviceSummaryResponse,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.OtpDeviceSummaryResponse,
+  TalerErrorDetail
 > {
   // return {
   //   ok: true,
@@ -139,14 +124,14 @@ export function useInstanceOtpDevices(
     error: afterError,
     isValidating: loadingAfter,
   } = useSWR<
-    HttpResponseOk<MerchantBackend.OTP.OtpDeviceSummaryResponse>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.OtpDeviceSummaryResponse>,
+    RequestError<TalerErrorDetail>
   >([`/private/otp-devices`], fetcher);
 
   const [lastAfter, setLastAfter] = useState<
     HttpResponse<
-      MerchantBackend.OTP.OtpDeviceSummaryResponse,
-      MerchantBackend.ErrorDetail
+      TalerMerchantApi.OtpDeviceSummaryResponse,
+      TalerErrorDetail
     >
   >({ loading: true });
   useEffect(() => {
@@ -190,8 +175,8 @@ export function useInstanceOtpDevices(
 export function useOtpDeviceDetails(
   deviceId: string,
 ): HttpResponse<
-  MerchantBackend.OTP.OtpDeviceDetails,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.OtpDeviceDetails,
+  TalerErrorDetail
 > {
   // return {
   //   ok: true,
@@ -204,8 +189,8 @@ export function useOtpDeviceDetails(
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
-    HttpResponseOk<MerchantBackend.OTP.OtpDeviceDetails>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.OtpDeviceDetails>,
+    RequestError<TalerErrorDetail>
   >([`/private/otp-devices/${deviceId}`], fetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
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..5a50eb378
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/preference.ts
@@ -0,0 +1,86 @@
+/*
+ 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,
+  (s: Preferences) => 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, update];
+}
+
+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..64dbd0103 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
@@ -21,7 +21,6 @@
 
 import * as tests from "@gnu-taler/web-util/testing";
 import { expect } from "chai";
-import { MerchantBackend } from "../declaration.js";
 import {
   useInstanceProducts,
   useProductAPI,
@@ -35,6 +34,7 @@ import {
   API_LIST_PRODUCTS,
   API_UPDATE_PRODUCT_BY_ID,
 } from "./urls.js";
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 
 describe("product api interaction with listing", () => {
   it("should evict cache when creating a product", async () => {
@@ -42,11 +42,11 @@ describe("product api interaction with listing", () => {
 
     env.addRequestExpectation(API_LIST_PRODUCTS, {
       response: {
-        products: [{ product_id: "1234" }],
+        products: [{ product_id: "1234", product_serial: 1 }],
       },
     });
     env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
-      response: { price: "ARS:12" } as MerchantBackend.Products.ProductDetail,
+      response: { price: "ARS:12" } as TalerMerchantApi.ProductDetail,
     });
 
     const hookBehavior = await tests.hookBehaveLikeThis(
@@ -70,33 +70,33 @@ describe("product api interaction with listing", () => {
           expect(query.loading).undefined;
           expect(query.ok).true;
           if (!query.ok) return;
-          expect(query.data).deep.equals([{ id: "1234", price: "ARS:12" }]);
+          expect(query.data).deep.equals([{ id: "1234" , price: "ARS:12" }]);
 
           env.addRequestExpectation(API_CREATE_PRODUCT, {
             request: {
               price: "ARS:23",
-            } as MerchantBackend.Products.ProductAddDetail,
+            } as TalerMerchantApi.ProductAddDetail,
           });
 
           env.addRequestExpectation(API_LIST_PRODUCTS, {
             response: {
-              products: [{ product_id: "1234" }, { product_id: "2345" }],
+              products: [{ product_id: "1234", product_serial: 1 }, { 
product_id: "2345", product_serial: 2 }],
             },
           });
           env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
             response: {
               price: "ARS:12",
-            } as MerchantBackend.Products.ProductDetail,
+            } as TalerMerchantApi.ProductDetail,
           });
           env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
             response: {
               price: "ARS:12",
-            } as MerchantBackend.Products.ProductDetail,
+            } as TalerMerchantApi.ProductDetail,
           });
           env.addRequestExpectation(API_GET_PRODUCT_BY_ID("2345"), {
             response: {
               price: "ARS:23",
-            } as MerchantBackend.Products.ProductDetail,
+            } as TalerMerchantApi.ProductDetail,
           });
 
           api.createProduct({
@@ -140,11 +140,11 @@ describe("product api interaction with listing", () => {
 
     env.addRequestExpectation(API_LIST_PRODUCTS, {
       response: {
-        products: [{ product_id: "1234" }],
+        products: [{ product_id: "1234", product_serial: 1 }],
       },
     });
     env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
-      response: { price: "ARS:12" } as MerchantBackend.Products.ProductDetail,
+      response: { price: "ARS:12" } as TalerMerchantApi.ProductDetail,
     });
 
     const hookBehavior = await tests.hookBehaveLikeThis(
@@ -173,18 +173,18 @@ describe("product api interaction with listing", () => {
           env.addRequestExpectation(API_UPDATE_PRODUCT_BY_ID("1234"), {
             request: {
               price: "ARS:13",
-            } as MerchantBackend.Products.ProductPatchDetail,
+            } as TalerMerchantApi.ProductPatchDetail,
           });
 
           env.addRequestExpectation(API_LIST_PRODUCTS, {
             response: {
-              products: [{ product_id: "1234" }],
+              products: [{ product_id: "1234", product_serial: 1 }],
             },
           });
           env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
             response: {
               price: "ARS:13",
-            } as MerchantBackend.Products.ProductDetail,
+            } as TalerMerchantApi.ProductDetail,
           });
 
           api.updateProduct("1234", {
@@ -218,14 +218,14 @@ describe("product api interaction with listing", () => {
 
     env.addRequestExpectation(API_LIST_PRODUCTS, {
       response: {
-        products: [{ product_id: "1234" }, { product_id: "2345" }],
+        products: [{ product_id: "1234" , product_serial: 1}, { product_id: 
"2345", product_serial: 2 }],
       },
     });
     env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
-      response: { price: "ARS:12" } as MerchantBackend.Products.ProductDetail,
+      response: { price: "ARS:12" } as TalerMerchantApi.ProductDetail,
     });
     env.addRequestExpectation(API_GET_PRODUCT_BY_ID("2345"), {
-      response: { price: "ARS:23" } as MerchantBackend.Products.ProductDetail,
+      response: { price: "ARS:23" } as TalerMerchantApi.ProductDetail,
     });
 
     const hookBehavior = await tests.hookBehaveLikeThis(
@@ -258,14 +258,14 @@ describe("product api interaction with listing", () => {
 
           env.addRequestExpectation(API_LIST_PRODUCTS, {
             response: {
-              products: [{ product_id: "1234" }],
+              products: [{ product_id: "1234", product_serial: 1 }],
             },
           });
 
           env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
             response: {
               price: "ARS:12",
-            } as MerchantBackend.Products.ProductDetail,
+            } as TalerMerchantApi.ProductDetail,
           });
           api.deleteProduct("2345");
         },
@@ -300,7 +300,7 @@ describe("product api interaction with details", () => {
     env.addRequestExpectation(API_GET_PRODUCT_BY_ID("12"), {
       response: {
         description: "this is a description",
-      } as MerchantBackend.Products.ProductDetail,
+      } as TalerMerchantApi.ProductDetail,
     });
 
     const hookBehavior = await tests.hookBehaveLikeThis(
@@ -328,13 +328,13 @@ describe("product api interaction with details", () => {
           env.addRequestExpectation(API_UPDATE_PRODUCT_BY_ID("12"), {
             request: {
               description: "other description",
-            } as MerchantBackend.Products.ProductPatchDetail,
+            } as TalerMerchantApi.ProductPatchDetail,
           });
 
           env.addRequestExpectation(API_GET_PRODUCT_BY_ID("12"), {
             response: {
               description: "other description",
-            } as MerchantBackend.Products.ProductDetail,
+            } as TalerMerchantApi.ProductDetail,
           });
 
           api.updateProduct("12", {
diff --git a/packages/merchant-backoffice-ui/src/hooks/product.ts 
b/packages/merchant-backoffice-ui/src/hooks/product.ts
index b54cd4d91..c0ace0d32 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
@@ -18,11 +18,11 @@ import {
   HttpResponseOk,
   RequestError,
 } from "@gnu-taler/web-util/browser";
-import { MerchantBackend, WithId } from "../declaration.js";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
 import _useSWR, { SWRHook, useSWRConfig } from "swr";
+import { TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
 const useSWR = _useSWR as unknown as SWRHook;
 
 export interface ProductAPI {
@@ -30,16 +30,16 @@ export interface ProductAPI {
     id: string,  
   ) => Promise<void>;
   createProduct: (
-    data: MerchantBackend.Products.ProductAddDetail,
+    data: TalerMerchantApi.ProductAddDetail,
   ) => Promise<void>;
   updateProduct: (
     id: string,
-    data: MerchantBackend.Products.ProductPatchDetail,
+    data: TalerMerchantApi.ProductPatchDetail,
   ) => Promise<void>;
   deleteProduct: (id: string) => Promise<void>;
   lockProduct: (
     id: string,
-    data: MerchantBackend.Products.LockRequest,
+    data: TalerMerchantApi.LockRequest,
   ) => Promise<void>;
 }
 
@@ -50,7 +50,7 @@ export function useProductAPI(): ProductAPI {
   const { request } = useBackendInstanceRequest();
 
   const createProduct = async (
-    data: MerchantBackend.Products.ProductAddDetail,
+    data: TalerMerchantApi.ProductAddDetail,
   ): Promise<void> => {
     const res = await request(`/private/products`, {
       method: "POST",
@@ -62,7 +62,7 @@ export function useProductAPI(): ProductAPI {
 
   const updateProduct = async (
     productId: string,
-    data: MerchantBackend.Products.ProductPatchDetail,
+    data: TalerMerchantApi.ProductPatchDetail,
   ): Promise<void> => {
     const r = await request(`/private/products/${productId}`, {
       method: "PATCH",
@@ -81,7 +81,7 @@ export function useProductAPI(): ProductAPI {
 
   const lockProduct = async (
     productId: string,
-    data: MerchantBackend.Products.LockRequest,
+    data: TalerMerchantApi.LockRequest,
   ): Promise<void> => {
     await request(`/private/products/${productId}/lock`, {
       method: "POST",
@@ -105,14 +105,14 @@ export function useProductAPI(): ProductAPI {
 }
 
 export function useInstanceProducts(): HttpResponse<
-  (MerchantBackend.Products.ProductDetail & WithId)[],
-  MerchantBackend.ErrorDetail
+  (TalerMerchantApi.ProductDetail & WithId)[],
+  TalerErrorDetail
 > {
   const { fetcher, multiFetcher } = useBackendInstanceRequest();
 
   const { data: list, error: listError } = useSWR<
-    HttpResponseOk<MerchantBackend.Products.InventorySummaryResponse>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.InventorySummaryResponse>,
+    RequestError<TalerErrorDetail>
   >([`/private/products`], fetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
@@ -125,8 +125,8 @@ export function useInstanceProducts(): HttpResponse<
     (p) => `/private/products/${p.product_id}`,
   );
   const { data: products, error: productError } = useSWR<
-    HttpResponseOk<MerchantBackend.Products.ProductDetail>[],
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.ProductDetail>[],
+    RequestError<TalerErrorDetail>
   >([paths], multiFetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
@@ -154,14 +154,14 @@ export function useInstanceProducts(): HttpResponse<
 export function useProductDetails(
   productId: string,
 ): HttpResponse<
-  MerchantBackend.Products.ProductDetail,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.ProductDetail,
+  TalerErrorDetail
 > {
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
-    HttpResponseOk<MerchantBackend.Products.ProductDetail>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.ProductDetail>,
+    RequestError<TalerErrorDetail>
   >([`/private/products/${productId}`], fetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
diff --git a/packages/merchant-backoffice-ui/src/hooks/reserve.test.ts 
b/packages/merchant-backoffice-ui/src/hooks/reserve.test.ts
deleted file mode 100644
index 186af1f61..000000000
--- a/packages/merchant-backoffice-ui/src/hooks/reserve.test.ts
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import * as tests from "@gnu-taler/web-util/testing";
-import { expect } from "chai";
-import { MerchantBackend } from "../declaration.js";
-import {
-  useInstanceReserves,
-  useReservesAPI,
-} from "./reserves.js";
-import { ApiMockEnvironment } from "./testing.js";
-import {
-  API_CREATE_RESERVE,
-  API_DELETE_RESERVE,
-  API_LIST_RESERVES
-} from "./urls.js";
-
-describe("reserve api interaction with listing", () => {
-  it("should evict cache when creating a reserve", async () => {
-    const env = new ApiMockEnvironment();
-
-    env.addRequestExpectation(API_LIST_RESERVES, {
-      response: {
-        reserves: [
-          {
-            reserve_pub: "11",
-          } as MerchantBackend.Rewards.ReserveStatusEntry,
-        ],
-      },
-    });
-
-    const hookBehavior = await tests.hookBehaveLikeThis(
-      () => {
-        const api = useReservesAPI();
-        const query = useInstanceReserves();
-        return { query, api };
-      },
-      {},
-      [
-        ({ query, api }) => {
-          expect(query.loading).true;
-        },
-        ({ query, api }) => {
-          expect(query.loading).false;
-          expect(query.ok).true;
-          if (!query.ok) return;
-          expect(query.data).deep.equals({
-            reserves: [{ reserve_pub: "11" }],
-          });
-
-          env.addRequestExpectation(API_CREATE_RESERVE, {
-            request: {
-              initial_balance: "ARS:3333",
-              exchange_url: "http://url";,
-              wire_method: "iban",
-            },
-            response: {
-              reserve_pub: "22",
-              accounts: [],
-            },
-          });
-
-          env.addRequestExpectation(API_LIST_RESERVES, {
-            response: {
-              reserves: [
-                {
-                  reserve_pub: "11",
-                } as MerchantBackend.Rewards.ReserveStatusEntry,
-                {
-                  reserve_pub: "22",
-                } as MerchantBackend.Rewards.ReserveStatusEntry,
-              ],
-            },
-          });
-
-          api.createReserve({
-            initial_balance: "ARS:3333",
-            exchange_url: "http://url";,
-            wire_method: "iban",
-          });
-        },
-        ({ query, api }) => {
-          expect(env.assertJustExpectedRequestWereMade()).deep.eq({
-            result: "ok",
-          });
-          expect(query.loading).false;
-          expect(query.ok).true;
-          if (!query.ok) return;
-
-          expect(query.data).deep.equals({
-            reserves: [
-              {
-                reserve_pub: "11",
-              } as MerchantBackend.Rewards.ReserveStatusEntry,
-              {
-                reserve_pub: "22",
-              } as MerchantBackend.Rewards.ReserveStatusEntry,
-            ],
-          });
-        },
-      ],
-      env.buildTestingContext(),
-    );
-
-    expect(hookBehavior).deep.eq({ result: "ok" });
-    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" });
-  });
-
-  it("should evict cache when deleting a reserve", async () => {
-    const env = new ApiMockEnvironment();
-
-    env.addRequestExpectation(API_LIST_RESERVES, {
-      response: {
-        reserves: [
-          {
-            reserve_pub: "11",
-          } as MerchantBackend.Rewards.ReserveStatusEntry,
-          {
-            reserve_pub: "22",
-          } as MerchantBackend.Rewards.ReserveStatusEntry,
-          {
-            reserve_pub: "33",
-          } as MerchantBackend.Rewards.ReserveStatusEntry,
-        ],
-      },
-    });
-
-    const hookBehavior = await tests.hookBehaveLikeThis(
-      () => {
-        const api = useReservesAPI();
-        const query = useInstanceReserves();
-        return { query, api };
-      },
-      {},
-      [
-        ({ query, api }) => {
-          expect(query.loading).true;
-        },
-        ({ query, api }) => {
-          expect(env.assertJustExpectedRequestWereMade()).deep.eq({
-            result: "ok",
-          });
-
-          expect(query.loading).false;
-          expect(query.ok).true;
-          if (!query.ok) return;
-          expect(query.data).deep.equals({
-            reserves: [
-              { reserve_pub: "11" },
-              { reserve_pub: "22" },
-              { reserve_pub: "33" },
-            ],
-          });
-
-          env.addRequestExpectation(API_DELETE_RESERVE("11"), {});
-          env.addRequestExpectation(API_LIST_RESERVES, {
-            response: {
-              reserves: [
-                {
-                  reserve_pub: "22",
-                } as MerchantBackend.Rewards.ReserveStatusEntry,
-                {
-                  reserve_pub: "33",
-                } as MerchantBackend.Rewards.ReserveStatusEntry,
-              ],
-            },
-          });
-
-          api.deleteReserve("11");
-        },
-        ({ query, api }) => {
-          expect(env.assertJustExpectedRequestWereMade()).deep.eq({
-            result: "ok",
-          });
-          expect(query.loading).false;
-          expect(query.ok).true;
-          if (!query.ok) return;
-          expect(query.data).deep.equals({
-            reserves: [{ reserve_pub: "22" }, { reserve_pub: "33" }],
-          });
-        },
-      ],
-      env.buildTestingContext(),
-    );
-
-    expect(hookBehavior).deep.eq({ result: "ok" });
-    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" });
-  });
-});
diff --git a/packages/merchant-backoffice-ui/src/hooks/reserves.ts 
b/packages/merchant-backoffice-ui/src/hooks/reserves.ts
deleted file mode 100644
index 62dc48412..000000000
--- a/packages/merchant-backoffice-ui/src/hooks/reserves.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2021-2023 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 {
-  HttpResponse,
-  HttpResponseOk,
-  RequestError,
-} from "@gnu-taler/web-util/browser";
-import { MerchantBackend } from "../declaration.js";
-import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
-
-// FIX default import https://github.com/microsoft/TypeScript/issues/49189
-import _useSWR, { SWRHook, useSWRConfig } from "swr";
-const useSWR = _useSWR as unknown as SWRHook;
-
-export function useReservesAPI(): ReserveMutateAPI {
-  const mutateAll = useMatchMutate();
-  const { mutate } = useSWRConfig();
-  const { request } = useBackendInstanceRequest();
-
-  const createReserve = async (
-    data: MerchantBackend.Rewards.ReserveCreateRequest,
-  ): Promise<
-    HttpResponseOk<MerchantBackend.Rewards.ReserveCreateConfirmation>
-  > => {
-    const res = await 
request<MerchantBackend.Rewards.ReserveCreateConfirmation>(
-      `/private/reserves`,
-      {
-        method: "POST",
-        data,
-      },
-    );
-
-    //evict reserve list query
-    await mutateAll(/.*private\/reserves.*/);
-
-    return res;
-  };
-
-
-  const deleteReserve = async (
-    pub: string,
-  ): Promise<HttpResponse<void, MerchantBackend.ErrorDetail>> => {
-    const res = await request<void>(`/private/reserves/${pub}`, {
-      method: "DELETE",
-    });
-
-    //evict reserve list query
-    await mutateAll(/.*private\/reserves.*/);
-
-    return res;
-  };
-
-  return { createReserve, deleteReserve };
-}
-
-export interface ReserveMutateAPI {
-  createReserve: (
-    data: MerchantBackend.Rewards.ReserveCreateRequest,
-  ) => 
Promise<HttpResponseOk<MerchantBackend.Rewards.ReserveCreateConfirmation>>;
-  deleteReserve: (
-    id: string,
-  ) => Promise<HttpResponse<void, MerchantBackend.ErrorDetail>>;
-}
-
-export function useInstanceReserves(): HttpResponse<
-  MerchantBackend.Rewards.RewardReserveStatus,
-  MerchantBackend.ErrorDetail
-> {
-  const { fetcher } = useBackendInstanceRequest();
-
-  const { data, error, isValidating } = useSWR<
-    HttpResponseOk<MerchantBackend.Rewards.RewardReserveStatus>,
-    RequestError<MerchantBackend.ErrorDetail>
-  >([`/private/reserves`], fetcher);
-
-  if (isValidating) return { loading: true, data: data?.data };
-  if (data) return data;
-  if (error) return error.cause;
-  return { loading: true };
-}
-
diff --git a/packages/merchant-backoffice-ui/src/hooks/templates.ts 
b/packages/merchant-backoffice-ui/src/hooks/templates.ts
index ee8728cc8..2e39a0c46 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
@@ -20,11 +20,11 @@ import {
   RequestError,
 } from "@gnu-taler/web-util/browser";
 import { useEffect, useState } from "preact/hooks";
-import { MerchantBackend } from "../declaration.js";
 import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils/constants.js";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
+import { TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
 import _useSWR, { SWRHook } from "swr";
 const useSWR = _useSWR as unknown as SWRHook;
 
@@ -33,7 +33,7 @@ export function useTemplateAPI(): TemplateAPI {
   const { request } = useBackendInstanceRequest();
 
   const createTemplate = async (
-    data: MerchantBackend.Template.TemplateAddDetails,
+    data: TalerMerchantApi.TemplateAddDetails,
   ): Promise<HttpResponseOk<void>> => {
     const res = await request<void>(`/private/templates`, {
       method: "POST",
@@ -45,7 +45,7 @@ export function useTemplateAPI(): TemplateAPI {
 
   const updateTemplate = async (
     templateId: string,
-    data: MerchantBackend.Template.TemplatePatchDetails,
+    data: TalerMerchantApi.TemplatePatchDetails,
   ): Promise<HttpResponseOk<void>> => {
     const res = await request<void>(`/private/templates/${templateId}`, {
       method: "PATCH",
@@ -67,11 +67,11 @@ export function useTemplateAPI(): TemplateAPI {
 
   const createOrderFromTemplate = async (
     templateId: string,
-    data: MerchantBackend.Template.UsingTemplateDetails,
+    data: TalerMerchantApi.UsingTemplateDetails,
   ): Promise<
-    HttpResponseOk<MerchantBackend.Template.UsingTemplateResponse>
+    HttpResponseOk<TalerMerchantApi.PostOrderResponse>
   > => {
-    const res = await request<MerchantBackend.Template.UsingTemplateResponse>(
+    const res = await request<TalerMerchantApi.PostOrderResponse>(
       `/templates/${templateId}`,
       {
         method: "POST",
@@ -101,11 +101,11 @@ export function useTemplateAPI(): TemplateAPI {
 
 export interface TemplateAPI {
   createTemplate: (
-    data: MerchantBackend.Template.TemplateAddDetails,
+    data: TalerMerchantApi.TemplateAddDetails,
   ) => Promise<HttpResponseOk<void>>;
   updateTemplate: (
     id: string,
-    data: MerchantBackend.Template.TemplatePatchDetails,
+    data: TalerMerchantApi.TemplatePatchDetails,
   ) => Promise<HttpResponseOk<void>>;
   testTemplateExist: (
     id: string
@@ -113,8 +113,8 @@ export interface TemplateAPI {
   deleteTemplate: (id: string) => Promise<HttpResponseOk<void>>;
   createOrderFromTemplate: (
     id: string,
-    data: MerchantBackend.Template.UsingTemplateDetails,
-  ) => Promise<HttpResponseOk<MerchantBackend.Template.UsingTemplateResponse>>;
+    data: TalerMerchantApi.UsingTemplateDetails,
+  ) => Promise<HttpResponseOk<TalerMerchantApi.PostOrderResponse>>;
 }
 
 export interface InstanceTemplateFilter {
@@ -126,8 +126,8 @@ export function useInstanceTemplates(
   args?: InstanceTemplateFilter,
   updatePosition?: (id: string) => void,
 ): HttpResponsePaginated<
-  MerchantBackend.Template.TemplateSummaryResponse,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.TemplateSummaryResponse,
+  TalerErrorDetail
 > {
   const { templateFetcher } = useBackendInstanceRequest();
 
@@ -148,8 +148,8 @@ export function useInstanceTemplates(
     error: beforeError,
     isValidating: loadingBefore,
   } = useSWR<
-    HttpResponseOk<MerchantBackend.Template.TemplateSummaryResponse>,
-    RequestError<MerchantBackend.ErrorDetail>>(
+    HttpResponseOk<TalerMerchantApi.TemplateSummaryResponse>,
+    RequestError<TalerErrorDetail>>(
       [
         `/private/templates`,
         args?.position,
@@ -162,22 +162,22 @@ export function useInstanceTemplates(
     error: afterError,
     isValidating: loadingAfter,
   } = useSWR<
-    HttpResponseOk<MerchantBackend.Template.TemplateSummaryResponse>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.TemplateSummaryResponse>,
+    RequestError<TalerErrorDetail>
   >([`/private/templates`, args?.position, -totalAfter], templateFetcher);
 
   //this will save last result
   const [lastBefore, setLastBefore] = useState<
     HttpResponse<
-      MerchantBackend.Template.TemplateSummaryResponse,
-      MerchantBackend.ErrorDetail
+      TalerMerchantApi.TemplateSummaryResponse,
+      TalerErrorDetail
     >
   >({ loading: true });
 
   const [lastAfter, setLastAfter] = useState<
     HttpResponse<
-      MerchantBackend.Template.TemplateSummaryResponse,
-      MerchantBackend.ErrorDetail
+      TalerMerchantApi.TemplateSummaryResponse,
+      TalerErrorDetail
     >
   >({ loading: true });
   useEffect(() => {
@@ -190,20 +190,20 @@ export function useInstanceTemplates(
 
   // if the query returns less that we ask, then we have reach the end or 
beginning
   const isReachingEnd =
-    afterData && afterData.data.templates.length < totalAfter;
+    afterData && afterData.data.templates_list.length < totalAfter;
   const isReachingStart = args?.position === undefined
     ||
-    (beforeData && beforeData.data.templates.length < totalBefore);
+    (beforeData && beforeData.data.templates_list.length < totalBefore);
 
   const pagination = {
     isReachingEnd,
     isReachingStart,
     loadMore: () => {
       if (!afterData || isReachingEnd) return;
-      if (afterData.data.templates.length < MAX_RESULT_SIZE) {
+      if (afterData.data.templates_list.length < MAX_RESULT_SIZE) {
         setPageAfter(pageAfter + 1);
       } else {
-        const from = 
`${afterData.data.templates[afterData.data.templates.length - 1]
+        const from = 
`${afterData.data.templates_list[afterData.data.templates_list.length - 1]
           .template_id
           }`;
         if (from && updatePosition) updatePosition(from);
@@ -211,10 +211,10 @@ export function useInstanceTemplates(
     },
     loadMorePrev: () => {
       if (!beforeData || isReachingStart) return;
-      if (beforeData.data.templates.length < MAX_RESULT_SIZE) {
+      if (beforeData.data.templates_list.length < MAX_RESULT_SIZE) {
         setPageBefore(pageBefore + 1);
       } else if (beforeData) {
-        const from = 
`${beforeData.data.templates[beforeData.data.templates.length - 1]
+        const from = 
`${beforeData.data.templates_list[beforeData.data.templates_list.length - 1]
           .template_id
           }`;
         if (from && updatePosition) updatePosition(from);
@@ -223,17 +223,17 @@ export function useInstanceTemplates(
   };
 
   // const templates = !afterData ? [] : (afterData || 
lastAfter).data.templates;
-  const templates =
+  const templates_list =
     !beforeData || !afterData
       ? []
-      : (beforeData || lastBefore).data.templates
+      : (beforeData || lastBefore).data.templates_list
         .slice()
         .reverse()
-        .concat((afterData || lastAfter).data.templates);
+        .concat((afterData || lastAfter).data.templates_list);
   if (loadingAfter || loadingBefore)
-    return { loading: true, data: { templates } };
+    return { loading: true, data: { templates_list } };
   if (beforeData && afterData) {
-    return { ok: true, data: { templates }, ...pagination };
+    return { ok: true, data: { templates_list }, ...pagination };
   }
   return { loading: true };
 }
@@ -241,14 +241,14 @@ export function useInstanceTemplates(
 export function useTemplateDetails(
   templateId: string,
 ): HttpResponse<
-  MerchantBackend.Template.TemplateDetails,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.TemplateDetails,
+  TalerErrorDetail
 > {
   const { templateFetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
-    HttpResponseOk<MerchantBackend.Template.TemplateDetails>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.TemplateDetails>,
+    RequestError<TalerErrorDetail>
   >([`/private/templates/${templateId}`], templateFetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
diff --git a/packages/merchant-backoffice-ui/src/hooks/testing.tsx 
b/packages/merchant-backoffice-ui/src/hooks/testing.tsx
index a0ba59b2e..bebf7716b 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
@@ -24,8 +24,6 @@ import { ComponentChildren, FunctionalComponent, h, VNode } 
from "preact";
 import { HttpRequestLibrary, HttpRequestOptions, HttpResponse } from 
"@gnu-taler/taler-util/http";
 import { SWRConfig } from "swr";
 import { ApiContextProvider } from "@gnu-taler/web-util/browser";
-import { BackendContextProvider } from "../context/backend.js";
-import { InstanceContextProvider } from "../context/instance.js";
 import { HttpResponseOk, RequestOptions } from "@gnu-taler/web-util/browser";
 import { TalerBankIntegrationHttpClient, TalerCoreBankHttpClient, 
TalerRevenueHttpClient, TalerWireGatewayHttpClient } from 
"@gnu-taler/taler-util";
 
@@ -149,15 +147,15 @@ export class ApiMockEnvironment extends MockEnvironment {
       const bankWire = new 
TalerWireGatewayHttpClient(bankCore.getWireGatewayAPI("b").href, "b", 
mockHttpClient)
 
       return (
-        <BackendContextProvider defaultUrl="http://backend";>
-          <InstanceContextProvider
-            value={{
-              token: undefined,
-              id: "default",
-              admin: true,
-              changeToken: () => null,
-            }}
-          >
+        // <BackendContextProvider defaultUrl="http://backend";>
+        //   <InstanceContextProvider
+        //     value={{
+        //       token: undefined,
+        //       id: "default",
+        //       admin: true,
+        //       changeToken: () => null,
+        //     }}
+        //   >
             <ApiContextProvider value={{ request, bankCore, bankIntegration, 
bankRevenue, bankWire }}>
               <SC
                 value={{
@@ -172,8 +170,8 @@ export class ApiMockEnvironment extends MockEnvironment {
                 {children}
               </SC>
             </ApiContextProvider>
-          </InstanceContextProvider>
-        </BackendContextProvider>
+        //   </InstanceContextProvider>
+        // </BackendContextProvider>
       );
     };
   }
diff --git a/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts 
b/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts
index a7187af27..ee987af7e 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
@@ -19,12 +19,12 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { AmountString, PaytoString, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import * as tests from "@gnu-taler/web-util/testing";
 import { expect } from "chai";
-import { MerchantBackend } from "../declaration.js";
-import { API_INFORM_TRANSFERS, API_LIST_TRANSFERS } from "./urls.js";
 import { ApiMockEnvironment } from "./testing.js";
 import { useInstanceTransfers, useTransferAPI } from "./transfer.js";
+import { API_INFORM_TRANSFERS, API_LIST_TRANSFERS } from "./urls.js";
 
 describe("transfer api interaction with listing", () => {
   it("should evict cache when informing a transfer", async () => {
@@ -33,7 +33,7 @@ describe("transfer api interaction with listing", () => {
     env.addRequestExpectation(API_LIST_TRANSFERS, {
       qparam: { limit: -20 },
       response: {
-        transfers: [{ wtid: "2" } as 
MerchantBackend.Transfers.TransferDetails],
+        transfers: [{ wtid: "2" } as TalerMerchantApi.TransferDetails],
       },
     });
 
@@ -83,9 +83,9 @@ describe("transfer api interaction with listing", () => {
 
           api.informTransfer({
             wtid: "3",
-            credit_amount: "EUR:1",
+            credit_amount: "EUR:1" as AmountString,
             exchange_url: "exchange.url",
-            payto_uri: "payto://",
+            payto_uri: "payto://" as PaytoString,
           });
         },
         ({ query, api }) => {
diff --git a/packages/merchant-backoffice-ui/src/hooks/transfer.ts 
b/packages/merchant-backoffice-ui/src/hooks/transfer.ts
index 27c3bdc75..20062a5e2 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
@@ -20,11 +20,11 @@ import {
   RequestError,
 } from "@gnu-taler/web-util/browser";
 import { useEffect, useState } from "preact/hooks";
-import { MerchantBackend } from "../declaration.js";
 import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils/constants.js";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
+import { TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
 import _useSWR, { SWRHook } from "swr";
 const useSWR = _useSWR as unknown as SWRHook;
 
@@ -33,7 +33,7 @@ export function useTransferAPI(): TransferAPI {
   const { request } = useBackendInstanceRequest();
 
   const informTransfer = async (
-    data: MerchantBackend.Transfers.TransferInformation,
+    data: TalerMerchantApi.TransferInformation,
   ): Promise<HttpResponseOk<{}>> => {
     const res = await request<{}>(`/private/transfers`, {
       method: "POST",
@@ -49,7 +49,7 @@ export function useTransferAPI(): TransferAPI {
 
 export interface TransferAPI {
   informTransfer: (
-    data: MerchantBackend.Transfers.TransferInformation,
+    data: TalerMerchantApi.TransferInformation,
   ) => Promise<HttpResponseOk<{}>>;
 }
 
@@ -63,8 +63,8 @@ export function useInstanceTransfers(
   args?: InstanceTransferFilter,
   updatePosition?: (id: string) => void,
 ): HttpResponsePaginated<
-  MerchantBackend.Transfers.TransferList,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.TransferList,
+  TalerErrorDetail
 > {
   const { transferFetcher } = useBackendInstanceRequest();
 
@@ -85,8 +85,8 @@ export function useInstanceTransfers(
     error: beforeError,
     isValidating: loadingBefore,
   } = useSWR<
-    HttpResponseOk<MerchantBackend.Transfers.TransferList>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.TransferList>,
+    RequestError<TalerErrorDetail>
   >(
     [
       `/private/transfers`,
@@ -102,8 +102,8 @@ export function useInstanceTransfers(
     error: afterError,
     isValidating: loadingAfter,
   } = useSWR<
-    HttpResponseOk<MerchantBackend.Transfers.TransferList>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.TransferList>,
+    RequestError<TalerErrorDetail>
   >(
     [
       `/private/transfers`,
@@ -118,14 +118,14 @@ export function useInstanceTransfers(
   //this will save last result
   const [lastBefore, setLastBefore] = useState<
     HttpResponse<
-      MerchantBackend.Transfers.TransferList,
-      MerchantBackend.ErrorDetail
+      TalerMerchantApi.TransferList,
+      TalerErrorDetail
     >
   >({ loading: true });
   const [lastAfter, setLastAfter] = useState<
     HttpResponse<
-      MerchantBackend.Transfers.TransferList,
-      MerchantBackend.ErrorDetail
+      TalerMerchantApi.TransferList,
+      TalerErrorDetail
     >
   >({ loading: true });
   useEffect(() => {
diff --git a/packages/merchant-backoffice-ui/src/hooks/urls.ts 
b/packages/merchant-backoffice-ui/src/hooks/urls.ts
index b6485259f..95e1c04f3 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
@@ -18,16 +18,16 @@
  *
  * @author Sebastian Javier Marchano (sebasjm)
  */
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { Query } from "@gnu-taler/web-util/testing";
-import { MerchantBackend } from "../declaration.js";
 
 ////////////////////
 // ORDER
 ////////////////////
 
 export const API_CREATE_ORDER: Query<
-  MerchantBackend.Orders.PostOrderRequest,
-  MerchantBackend.Orders.PostOrderResponse
+  TalerMerchantApi.PostOrderRequest,
+  TalerMerchantApi.PostOrderResponse
 > = {
   method: "POST",
   url: "http://backend/instances/default/private/orders";,
@@ -35,14 +35,14 @@ export const API_CREATE_ORDER: Query<
 
 export const API_GET_ORDER_BY_ID = (
   id: string,
-): Query<unknown, MerchantBackend.Orders.MerchantOrderStatusResponse> => ({
+): Query<unknown, TalerMerchantApi.MerchantOrderStatusResponse> => ({
   method: "GET",
   url: `http://backend/instances/default/private/orders/${id}`,
 });
 
 export const API_LIST_ORDERS: Query<
   unknown,
-  MerchantBackend.Orders.OrderHistory
+  TalerMerchantApi.OrderHistory
 > = {
   method: "GET",
   url: "http://backend/instances/default/private/orders";,
@@ -51,8 +51,8 @@ export const API_LIST_ORDERS: Query<
 export const API_REFUND_ORDER_BY_ID = (
   id: string,
 ): Query<
-  MerchantBackend.Orders.RefundRequest,
-  MerchantBackend.Orders.MerchantRefundResponse
+  TalerMerchantApi.RefundRequest,
+  TalerMerchantApi.MerchantRefundResponse
 > => ({
   method: "POST",
   url: `http://backend/instances/default/private/orders/${id}/refund`,
@@ -60,14 +60,14 @@ export const API_REFUND_ORDER_BY_ID = (
 
 export const API_FORGET_ORDER_BY_ID = (
   id: string,
-): Query<MerchantBackend.Orders.ForgetRequest, unknown> => ({
+): Query<TalerMerchantApi.ForgetRequest, unknown> => ({
   method: "PATCH",
   url: `http://backend/instances/default/private/orders/${id}/forget`,
 });
 
 export const API_DELETE_ORDER = (
   id: string,
-): Query<MerchantBackend.Orders.ForgetRequest, unknown> => ({
+): Query<TalerMerchantApi.ForgetRequest, unknown> => ({
   method: "DELETE",
   url: `http://backend/instances/default/private/orders/${id}`,
 });
@@ -78,14 +78,14 @@ export const API_DELETE_ORDER = (
 
 export const API_LIST_TRANSFERS: Query<
   unknown,
-  MerchantBackend.Transfers.TransferList
+  TalerMerchantApi.TransferList
 > = {
   method: "GET",
   url: "http://backend/instances/default/private/transfers";,
 };
 
 export const API_INFORM_TRANSFERS: Query<
-  MerchantBackend.Transfers.TransferInformation,
+  TalerMerchantApi.TransferInformation,
   {}
 > = {
   method: "POST",
@@ -97,7 +97,7 @@ export const API_INFORM_TRANSFERS: Query<
 ////////////////////
 
 export const API_CREATE_PRODUCT: Query<
-  MerchantBackend.Products.ProductAddDetail,
+  TalerMerchantApi.ProductAddDetail,
   unknown
 > = {
   method: "POST",
@@ -106,7 +106,7 @@ export const API_CREATE_PRODUCT: Query<
 
 export const API_LIST_PRODUCTS: Query<
   unknown,
-  MerchantBackend.Products.InventorySummaryResponse
+  TalerMerchantApi.InventorySummaryResponse
 > = {
   method: "GET",
   url: "http://backend/instances/default/private/products";,
@@ -114,7 +114,7 @@ export const API_LIST_PRODUCTS: Query<
 
 export const API_GET_PRODUCT_BY_ID = (
   id: string,
-): Query<unknown, MerchantBackend.Products.ProductDetail> => ({
+): Query<unknown, TalerMerchantApi.ProductDetail> => ({
   method: "GET",
   url: `http://backend/instances/default/private/products/${id}`,
 });
@@ -122,8 +122,8 @@ export const API_GET_PRODUCT_BY_ID = (
 export const API_UPDATE_PRODUCT_BY_ID = (
   id: string,
 ): Query<
-  MerchantBackend.Products.ProductPatchDetail,
-  MerchantBackend.Products.InventorySummaryResponse
+  TalerMerchantApi.ProductPatchDetail,
+  TalerMerchantApi.InventorySummaryResponse
 > => ({
   method: "PATCH",
   url: `http://backend/instances/default/private/products/${id}`,
@@ -134,68 +134,12 @@ export const API_DELETE_PRODUCT = (id: string): 
Query<unknown, unknown> => ({
   url: `http://backend/instances/default/private/products/${id}`,
 });
 
-////////////////////
-// RESERVES
-////////////////////
-
-export const API_CREATE_RESERVE: Query<
-  MerchantBackend.Rewards.ReserveCreateRequest,
-  MerchantBackend.Rewards.ReserveCreateConfirmation
-> = {
-  method: "POST",
-  url: "http://backend/instances/default/private/reserves";,
-};
-export const API_LIST_RESERVES: Query<
-  unknown,
-  MerchantBackend.Rewards.RewardReserveStatus
-> = {
-  method: "GET",
-  url: "http://backend/instances/default/private/reserves";,
-};
-
-export const API_GET_RESERVE_BY_ID = (
-  pub: string,
-): Query<unknown, MerchantBackend.Rewards.ReserveDetail> => ({
-  method: "GET",
-  url: `http://backend/instances/default/private/reserves/${pub}`,
-});
-
-export const API_GET_REWARD_BY_ID = (
-  pub: string,
-): Query<unknown, MerchantBackend.Rewards.RewardDetails> => ({
-  method: "GET",
-  url: `http://backend/instances/default/private/rewards/${pub}`,
-});
-
-export const API_AUTHORIZE_REWARD_FOR_RESERVE = (
-  pub: string,
-): Query<
-  MerchantBackend.Rewards.RewardCreateRequest,
-  MerchantBackend.Rewards.RewardCreateConfirmation
-> => ({
-  method: "POST",
-  url: 
`http://backend/instances/default/private/reserves/${pub}/authorize-reward`,
-});
-
-export const API_AUTHORIZE_REWARD: Query<
-  MerchantBackend.Rewards.RewardCreateRequest,
-  MerchantBackend.Rewards.RewardCreateConfirmation
-> = {
-  method: "POST",
-  url: `http://backend/instances/default/private/rewards`,
-};
-
-export const API_DELETE_RESERVE = (id: string): Query<unknown, unknown> => ({
-  method: "DELETE",
-  url: `http://backend/instances/default/private/reserves/${id}`,
-});
-
 ////////////////////
 // INSTANCE ADMIN
 ////////////////////
 
 export const API_CREATE_INSTANCE: Query<
-  MerchantBackend.Instances.InstanceConfigurationMessage,
+  TalerMerchantApi.InstanceConfigurationMessage,
   unknown
 > = {
   method: "POST",
@@ -204,21 +148,21 @@ export const API_CREATE_INSTANCE: Query<
 
 export const API_GET_INSTANCE_BY_ID = (
   id: string,
-): Query<unknown, MerchantBackend.Instances.QueryInstancesResponse> => ({
+): Query<unknown, TalerMerchantApi.QueryInstancesResponse> => ({
   method: "GET",
   url: `http://backend/management/instances/${id}`,
 });
 
 export const API_GET_INSTANCE_KYC_BY_ID = (
   id: string,
-): Query<unknown, MerchantBackend.KYC.AccountKycRedirects> => ({
+): Query<unknown, TalerMerchantApi.AccountKycRedirects> => ({
   method: "GET",
   url: `http://backend/management/instances/${id}/kyc`,
 });
 
 export const API_LIST_INSTANCES: Query<
   unknown,
-  MerchantBackend.Instances.InstancesResponse
+  TalerMerchantApi.InstancesResponse
 > = {
   method: "GET",
   url: "http://backend/management/instances";,
@@ -227,7 +171,7 @@ export const API_LIST_INSTANCES: Query<
 export const API_UPDATE_INSTANCE_BY_ID = (
   id: string,
 ): Query<
-  MerchantBackend.Instances.InstanceReconfigurationMessage,
+  TalerMerchantApi.InstanceReconfigurationMessage,
   unknown
 > => ({
   method: "PATCH",
@@ -237,7 +181,7 @@ export const API_UPDATE_INSTANCE_BY_ID = (
 export const API_UPDATE_INSTANCE_AUTH_BY_ID = (
   id: string,
 ): Query<
-  MerchantBackend.Instances.InstanceAuthConfigurationMessage,
+  TalerMerchantApi.InstanceAuthConfigurationMessage,
   unknown
 > => ({
   method: "POST",
@@ -249,25 +193,13 @@ export const API_DELETE_INSTANCE = (id: string): 
Query<unknown, unknown> => ({
   url: `http://backend/management/instances/${id}`,
 });
 
-////////////////////
-// AUTH
-////////////////////
-
-export const API_NEW_LOGIN: Query<
-  MerchantBackend.Instances.LoginTokenRequest,
-  unknown
-> = ({
-  method: "POST",
-  url: `http://backend/private/token`,
-});
-
 ////////////////////
 // INSTANCE
 ////////////////////
 
 export const API_GET_CURRENT_INSTANCE: Query<
   unknown,
-  MerchantBackend.Instances.QueryInstancesResponse
+  TalerMerchantApi.QueryInstancesResponse
 > = {
   method: "GET",
   url: `http://backend/instances/default/private/`,
@@ -275,14 +207,14 @@ export const API_GET_CURRENT_INSTANCE: Query<
 
 export const API_GET_CURRENT_INSTANCE_KYC: Query<
   unknown,
-  MerchantBackend.KYC.AccountKycRedirects
+  TalerMerchantApi.AccountKycRedirects
 > = {
   method: "GET",
   url: `http://backend/instances/default/private/kyc`,
 };
 
 export const API_UPDATE_CURRENT_INSTANCE: Query<
-  MerchantBackend.Instances.InstanceReconfigurationMessage,
+  TalerMerchantApi.InstanceReconfigurationMessage,
   unknown
 > = {
   method: "PATCH",
@@ -290,7 +222,7 @@ export const API_UPDATE_CURRENT_INSTANCE: Query<
 };
 
 export const API_UPDATE_CURRENT_INSTANCE_AUTH: Query<
-  MerchantBackend.Instances.InstanceAuthConfigurationMessage,
+  TalerMerchantApi.InstanceAuthConfigurationMessage,
   unknown
 > = {
   method: "POST",
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..4e62a81c9 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
@@ -20,11 +20,11 @@ import {
   RequestError,
 } from "@gnu-taler/web-util/browser";
 import { useEffect, useState } from "preact/hooks";
-import { MerchantBackend } from "../declaration.js";
 import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils/constants.js";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 // FIX default import https://github.com/microsoft/TypeScript/issues/49189
+import { TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
 import _useSWR, { SWRHook } from "swr";
 const useSWR = _useSWR as unknown as SWRHook;
 
@@ -33,7 +33,7 @@ export function useWebhookAPI(): WebhookAPI {
   const { request } = useBackendInstanceRequest();
 
   const createWebhook = async (
-    data: MerchantBackend.Webhooks.WebhookAddDetails,
+    data: TalerMerchantApi.WebhookAddDetails,
   ): Promise<HttpResponseOk<void>> => {
     const res = await request<void>(`/private/webhooks`, {
       method: "POST",
@@ -45,7 +45,7 @@ export function useWebhookAPI(): WebhookAPI {
 
   const updateWebhook = async (
     webhookId: string,
-    data: MerchantBackend.Webhooks.WebhookPatchDetails,
+    data: TalerMerchantApi.WebhookPatchDetails,
   ): Promise<HttpResponseOk<void>> => {
     const res = await request<void>(`/private/webhooks/${webhookId}`, {
       method: "PATCH",
@@ -70,11 +70,11 @@ export function useWebhookAPI(): WebhookAPI {
 
 export interface WebhookAPI {
   createWebhook: (
-    data: MerchantBackend.Webhooks.WebhookAddDetails,
+    data: TalerMerchantApi.WebhookAddDetails,
   ) => Promise<HttpResponseOk<void>>;
   updateWebhook: (
     id: string,
-    data: MerchantBackend.Webhooks.WebhookPatchDetails,
+    data: TalerMerchantApi.WebhookPatchDetails,
   ) => Promise<HttpResponseOk<void>>;
   deleteWebhook: (id: string) => Promise<HttpResponseOk<void>>;
 }
@@ -88,8 +88,8 @@ export function useInstanceWebhooks(
   args?: InstanceWebhookFilter,
   updatePosition?: (id: string) => void,
 ): HttpResponsePaginated<
-  MerchantBackend.Webhooks.WebhookSummaryResponse,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.WebhookSummaryResponse,
+  TalerErrorDetail
 > {
   const { webhookFetcher } = useBackendInstanceRequest();
 
@@ -104,14 +104,15 @@ export function useInstanceWebhooks(
     error: afterError,
     isValidating: loadingAfter,
   } = useSWR<
-    HttpResponseOk<MerchantBackend.Webhooks.WebhookSummaryResponse>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.WebhookSummaryResponse>,
+    RequestError<TalerErrorDetail>
+
   >([`/private/webhooks`, args?.position, -totalAfter], webhookFetcher);
 
   const [lastAfter, setLastAfter] = useState<
     HttpResponse<
-      MerchantBackend.Webhooks.WebhookSummaryResponse,
-      MerchantBackend.ErrorDetail
+      TalerMerchantApi.WebhookSummaryResponse,
+      TalerErrorDetail
     >
   >({ loading: true });
   useEffect(() => {
@@ -155,14 +156,14 @@ export function useInstanceWebhooks(
 export function useWebhookDetails(
   webhookId: string,
 ): HttpResponse<
-  MerchantBackend.Webhooks.WebhookDetails,
-  MerchantBackend.ErrorDetail
+  TalerMerchantApi.WebhookDetails,
+  TalerErrorDetail
 > {
   const { webhookFetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
-    HttpResponseOk<MerchantBackend.Webhooks.WebhookDetails>,
-    RequestError<MerchantBackend.ErrorDetail>
+    HttpResponseOk<TalerMerchantApi.WebhookDetails>,
+    RequestError<TalerErrorDetail>
   >([`/private/webhooks/${webhookId}`], webhookFetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
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..39fdb6bdc 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
@@ -20,8 +20,8 @@
  */
 
 import { h, VNode, FunctionalComponent } from "preact";
-import { ConfigContextProvider } from "../../../context/config.js";
 import { CreatePage as TestedComponent } from "./CreatePage.js";
+import { MerchantApiProviderTesting } from "@gnu-taler/web-util/browser";
 
 export default {
   title: "Pages/Instance/Create",
@@ -37,19 +37,32 @@ function createExample<Props>(
   props: Partial<Props>,
 ) {
   const r = (args: any) => (
-    <ConfigContextProvider
+    <MerchantApiProviderTesting
       value={{
-        currency: "ARS",
-        version: "1",
-        currencies: {
-          currency: "TESTKUDOS"
+        cancelRequest: () => {},
+        config: {
+          currency: "ARS",
+          version: "1",
+          currencies: {
+            "ASD": {
+              name: "testkudos",
+              alt_unit_names: {},
+              num_fractional_input_digits: 1,
+              num_fractional_normal_digits: 1,
+              num_fractional_trailing_zero_digits: 1,
+            }
+          },
+          exchanges: [],
+          name: "taler-merchant"
         },
-        exchanges: [],
-        name: "taler-merchant"
+        hints: [],
+        lib: {} as any,
+        onActivity: (() => {}) as any,
+        url: new URL("asdasd"),
       }}
     >
       <Component {...args} />
-    </ConfigContextProvider>
+    </MerchantApiProviderTesting>
   );
   r.args = props;
   return r;
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..731ea8939 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
@@ -19,6 +19,7 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { Duration, TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { useState } from "preact/hooks";
@@ -28,20 +29,18 @@ import {
   FormProvider,
 } from "../../../components/form/FormProvider.js";
 import { DefaultInstanceFormFields } from 
"../../../components/instance/DefaultInstanceFormFields.js";
-import { MerchantBackend } from "../../../declaration.js";
+import { SetTokenNewInstanceModal } from "../../../components/modal/index.js";
 import { INSTANCE_ID_REGEX } from "../../../utils/constants.js";
 import { undefinedIfEmpty } from "../../../utils/table.js";
-import { SetTokenNewInstanceModal } from "../../../components/modal/index.js";
-import { Duration } from "@gnu-taler/taler-util";
 
-export type Entity = 
Omit<Omit<MerchantBackend.Instances.InstanceConfigurationMessage, 
"default_pay_delay">, "default_wire_transfer_delay"> & {
+export type Entity = Omit<Omit<TalerMerchantApi.InstanceConfigurationMessage, 
"default_pay_delay">, "default_wire_transfer_delay"> & {
   auth_token?: string;
   default_pay_delay: Duration,
   default_wire_transfer_delay: Duration,
 };
 
 interface Props {
-  onCreate: (d: MerchantBackend.Instances.InstanceConfigurationMessage) => 
Promise<void>;
+  onCreate: (d: TalerMerchantApi.InstanceConfigurationMessage) => 
Promise<void>;
   onBack?: () => void;
   forceId?: string;
 }
@@ -134,7 +133,7 @@ export function CreatePage({ onCreate, onBack, forceId }: 
Props): VNode {
     // delete value.default_pay_delay;
     // delete value.default_wire_transfer_delay;
 
-    return onCreate(newValue as any as 
MerchantBackend.Instances.InstanceConfigurationMessage);
+    return onCreate(newValue as any as 
TalerMerchantApi.InstanceConfigurationMessage);
   };
 
   function updateToken(token: string | null) {
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..0e8ea1f5b 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
@@ -17,30 +17,32 @@
  *
  * @author Sebastian Javier Marchano (sebasjm)
  */
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
+import {
+  useMerchantApiContext,
+  useTranslationContext,
+} from "@gnu-taler/web-util/browser";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { NotificationCard } from "../../../components/menu/index.js";
-import { AccessToken, MerchantBackend } from "../../../declaration.js";
-import { useAdminAPI, useInstanceAPI } from "../../../hooks/instance.js";
+import { useSessionContext } from "../../../context/session.js";
+import { useAdminAPI } from "../../../hooks/instance.js";
 import { Notification } from "../../../utils/types.js";
 import { CreatePage } from "./CreatePage.js";
-import { useCredentialsChecker } from "../../../hooks/backend.js";
-import { useBackendContext } from "../../../context/backend.js";
 
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
   forceId?: string;
 }
-export type Entity = MerchantBackend.Instances.InstanceConfigurationMessage;
+export type Entity = TalerMerchantApi.InstanceConfigurationMessage;
 
 export default function Create({ onBack, onConfirm, forceId }: Props): VNode {
   const { createInstance } = useAdminAPI();
   const [notif, setNotif] = useState<Notification | undefined>(undefined);
   const { i18n } = useTranslationContext();
-  const { requestNewLoginToken } = useCredentialsChecker()
-  const { url: backendURL, updateToken } = useBackendContext()
+  const { lib } = useMerchantApiContext();
+  const { logIn } = useSessionContext();
 
   return (
     <Fragment>
@@ -50,17 +52,24 @@ export default function Create({ onBack, onConfirm, forceId 
}: Props): VNode {
         onBack={onBack}
         forceId={forceId}
         onCreate={async (
-          d: MerchantBackend.Instances.InstanceConfigurationMessage,
+          d: TalerMerchantApi.InstanceConfigurationMessage,
         ) => {
           try {
-            await createInstance(d)
+            await createInstance(d);
             if (d.auth.token) {
-              const resp = await requestNewLoginToken(backendURL, d.auth.token 
as AccessToken)
-              if (resp.valid) {
-                const { token, expiration } = resp
-                updateToken({ token, expiration });
-              } else {
-                updateToken(undefined)
+              const result = await lib.authenticate.createAccessTokenBearer(
+                d.auth.token,
+                {
+                  scope: "write",
+                  duration: {
+                    d_us: "forever",
+                  },
+                  refreshable: true,
+                },
+              );
+              if (result.type === "ok") {
+                const { token } = result.body;
+                logIn({ token });
               }
             }
             onConfirm();
@@ -72,7 +81,7 @@ export default function Create({ onBack, onConfirm, forceId 
}: Props): VNode {
                 description: ex.message,
               });
             } else {
-              console.error(ex)
+              console.error(ex);
             }
           }
         }}
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..8166dc739 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
@@ -19,9 +19,9 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { h, VNode, FunctionalComponent } from "preact";
-import { ConfigContextProvider } from "../../../context/config.js";
+import { FunctionalComponent, h } from "preact";
 import { CreatePage as TestedComponent } from "./CreatePage.js";
+import { MerchantApiProviderTesting } from "@gnu-taler/web-util/browser";
 
 export default {
   title: "Pages/Instance/Create",
@@ -37,19 +37,32 @@ function createExample<Props>(
   props: Partial<Props>,
 ) {
   const component = (args: any) => (
-    <ConfigContextProvider
+    <MerchantApiProviderTesting
       value={{
-        currency: "TESTKUDOS",
-        version: "1",
-        currencies: {
-          currency: "TESTKUDOS"
+        cancelRequest: () => {},
+        config: {
+          currency: "ARS",
+          version: "1",
+          currencies: {
+            "ASD": {
+              name: "testkudos",
+              alt_unit_names: {},
+              num_fractional_input_digits: 1,
+              num_fractional_normal_digits: 1,
+              num_fractional_trailing_zero_digits: 1,
+            }
+          },
+          exchanges: [],
+          name: "taler-merchant"
         },
-        exchanges: [],
-        name: "taler-merchant"
+        hints: [],
+        lib: {} as any,
+        onActivity: (() => {}) as any,
+        url: new URL("asdasd"),
       }}
     >
       <Internal {...(props as any)} />
-    </ConfigContextProvider>
+    </MerchantApiProviderTesting>
   );
   return { component, props };
 }
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..a03a2659b 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
@@ -19,19 +19,19 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { StateUpdater, useEffect, useState } from "preact/hooks";
-import { MerchantBackend } from "../../../declaration.js";
+import { useSessionContext } from "../../../context/session.js";
 
 interface Props {
-  instances: MerchantBackend.Instances.Instance[];
+  instances: TalerMerchantApi.Instance[];
   onUpdate: (id: string) => void;
-  onDelete: (id: MerchantBackend.Instances.Instance) => void;
-  onPurge: (id: MerchantBackend.Instances.Instance) => void;
+  onDelete: (id: TalerMerchantApi.Instance) => void;
+  onPurge: (id: TalerMerchantApi.Instance) => void;
   onCreate: () => void;
   selected?: boolean;
-  setInstanceName: (s: string) => void;
 }
 
 export function CardTable({
@@ -39,7 +39,6 @@ export function CardTable({
   onCreate,
   onUpdate,
   onPurge,
-  setInstanceName,
   onDelete,
   selected,
 }: Props): VNode {
@@ -114,7 +113,6 @@ export function CardTable({
                 instances={instances}
                 onPurge={onPurge}
                 onUpdate={onUpdate}
-                setInstanceName={setInstanceName}
                 onDelete={onDelete}
                 rowSelection={rowSelection}
                 rowSelectionHandler={rowSelectionHandler}
@@ -130,12 +128,11 @@ export function CardTable({
 }
 interface TableProps {
   rowSelection: string[];
-  instances: MerchantBackend.Instances.Instance[];
+  instances: TalerMerchantApi.Instance[];
   onUpdate: (id: string) => void;
-  onDelete: (id: MerchantBackend.Instances.Instance) => void;
-  onPurge: (id: MerchantBackend.Instances.Instance) => void;
+  onDelete: (id: TalerMerchantApi.Instance) => void;
+  onPurge: (id: TalerMerchantApi.Instance) => void;
   rowSelectionHandler: StateUpdater<string[]>;
-  setInstanceName: (s: string) => void;
 }
 
 function toggleSelected<T>(id: T): (prev: T[]) => T[] {
@@ -146,13 +143,13 @@ function toggleSelected<T>(id: T): (prev: T[]) => T[] {
 function Table({
   rowSelection,
   rowSelectionHandler,
-  setInstanceName,
   instances,
   onUpdate,
   onDelete,
   onPurge,
 }: TableProps): VNode {
   const { i18n } = useTranslationContext();
+  const { impersonate } = useSessionContext()
   return (
     <div class="table-container">
       <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
@@ -203,7 +200,8 @@ function Table({
                   <a
                     href={`#/orders?instance=${i.id}`}
                     onClick={(e) => {
-                      setInstanceName(i.id);
+                      impersonate({instance: i.id});
+                      e.preventDefault();
                     }}
                   >
                     {i.id}
@@ -267,7 +265,7 @@ function EmptyTable(): VNode {
 }
 
 interface Actions {
-  element: MerchantBackend.Instances.Instance;
+  element: TalerMerchantApi.Instance;
   type: "DELETE" | "UPDATE";
 }
 
@@ -276,7 +274,7 @@ function notEmpty<TValue>(value: TValue | null | 
undefined): value is TValue {
 }
 
 function buildActions(
-  instances: MerchantBackend.Instances.Instance[],
+  instances: TalerMerchantApi.Instance[],
   selected: string[],
   action: "DELETE",
 ): Actions[] {
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..940d14334 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
@@ -19,20 +19,19 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { useState } from "preact/hooks";
-import { MerchantBackend } from "../../../declaration.js";
 import { CardTable as CardTableActive } from "./TableActive.js";
 
 interface Props {
-  instances: MerchantBackend.Instances.Instance[];
+  instances: TalerMerchantApi.Instance[];
   onCreate: () => void;
   onUpdate: (id: string) => void;
-  onDelete: (id: MerchantBackend.Instances.Instance) => void;
-  onPurge: (id: MerchantBackend.Instances.Instance) => void;
+  onDelete: (id: TalerMerchantApi.Instance) => void;
+  onPurge: (id: TalerMerchantApi.Instance) => void;
   selected?: boolean;
-  setInstanceName: (s: string) => void;
 }
 
 export function View({
@@ -41,7 +40,6 @@ export function View({
   onDelete,
   onPurge,
   onUpdate,
-  setInstanceName,
   selected,
 }: Props): VNode {
   const [show, setShow] = useState<"active" | "deleted" | null>("active");
@@ -100,7 +98,6 @@ export function View({
         instances={showingInstances}
         onDelete={onDelete}
         onPurge={onPurge}
-        setInstanceName={setInstanceName}
         onUpdate={onUpdate}
         selected={selected}
         onCreate={onCreate}
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..d3fa78b65 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
@@ -19,30 +19,28 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../components/exception/loading.js";
 import { NotificationCard } from "../../../components/menu/index.js";
 import { DeleteModal, PurgeModal } from "../../../components/modal/index.js";
-import { MerchantBackend } from "../../../declaration.js";
 import { useAdminAPI, useBackendInstances } from "../../../hooks/instance.js";
 import { Notification } from "../../../utils/types.js";
 import { View } from "./View.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
 
 interface Props {
   onCreate: () => void;
   onUpdate: (id: string) => void;
-  instances: MerchantBackend.Instances.Instance[];
+  instances: TalerMerchantApi.Instance[];
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
-  setInstanceName: (s: string) => void;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
 }
 
 export default function Instances({
@@ -51,13 +49,12 @@ export default function Instances({
   onNotFound,
   onCreate,
   onUpdate,
-  setInstanceName,
 }: Props): VNode {
   const result = useBackendInstances();
   const [deleting, setDeleting] =
-    useState<MerchantBackend.Instances.Instance | null>(null);
+    useState<TalerMerchantApi.Instance | null>(null);
   const [purging, setPurging] =
-    useState<MerchantBackend.Instances.Instance | null>(null);
+    useState<TalerMerchantApi.Instance | null>(null);
   const { deleteInstance, purgeInstance } = useAdminAPI();
   const [notif, setNotif] = useState<Notification | undefined>(undefined);
   const { i18n } = useTranslationContext();
@@ -86,7 +83,6 @@ export default function Instances({
         onCreate={onCreate}
         onPurge={setPurging}
         onUpdate={onUpdate}
-        setInstanceName={setInstanceName}
         selected={!!deleting}
       />
       {deleting && (
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..dd77d609c 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
@@ -19,6 +19,7 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
@@ -30,13 +31,12 @@ import {
 import { Input } from "../../../../components/form/Input.js";
 import { InputPaytoForm } from "../../../../components/form/InputPaytoForm.js";
 import { InputSelector } from "../../../../components/form/InputSelector.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { undefinedIfEmpty } from "../../../../utils/table.js";
 
-type Entity = MerchantBackend.BankAccounts.AccountAddDetails & { 
repeatPassword: string };
+type Entity = TalerMerchantApi.AccountAddDetails & { repeatPassword: string };
 
 interface Props {
-  onCreate: (d: MerchantBackend.BankAccounts.AccountAddDetails) => 
Promise<void>;
+  onCreate: (d: TalerMerchantApi.AccountAddDetails) => Promise<void>;
   onBack?: () => void;
 }
 
@@ -89,7 +89,7 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
   const submitForm = () => {
     if (hasErrors) return Promise.reject();
     const credit_facade_url = !state.credit_facade_url ? undefined : new 
URL("/", state.credit_facade_url).href
-    const credit_facade_credentials: 
MerchantBackend.BankAccounts.FacadeCredentials | undefined =
+    const credit_facade_credentials: TalerMerchantApi.FacadeCredentials | 
undefined =
       credit_facade_url == undefined ? undefined :
         state.credit_facade_credentials?.type === "basic" ? {
           type: "basic",
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..b12b95f2f 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
@@ -19,16 +19,16 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useBankAccountAPI } from "../../../../hooks/bank.js";
 import { Notification } from "../../../../utils/types.js";
 import { CreatePage } from "./CreatePage.js";
 
-export type Entity = MerchantBackend.BankAccounts.AccountAddDetails;
+export type Entity = TalerMerchantApi.AccountAddDetails;
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
@@ -46,7 +46,7 @@ export default function CreateValidator({ onConfirm, onBack 
}: Props): VNode {
         onBack={onBack}
         onCreate={(request: Entity) => {
           return createBankAccount(request)
-            .then((d) => {
+            .then(() => {
               onConfirm()
             })
             .catch((error) => {
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..50cf0fe70 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
@@ -19,18 +19,17 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { h, VNode } from "preact";
-import { MerchantBackend } from "../../../../declaration.js";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { CardTable } from "./Table.js";
 
 export interface Props {
-  devices: MerchantBackend.BankAccounts.BankAccountEntry[];
+  devices: TalerMerchantApi.BankAccountEntry[];
   onLoadMoreBefore?: () => void;
   onLoadMoreAfter?: () => void;
   onCreate: () => void;
-  onDelete: (e: MerchantBackend.BankAccounts.BankAccountEntry) => void;
-  onSelect: (e: MerchantBackend.BankAccounts.BankAccountEntry) => void;
+  onDelete: (e: TalerMerchantApi.BankAccountEntry) => void;
+  onSelect: (e: TalerMerchantApi.BankAccountEntry) => void;
 }
 
 export function ListPage({
@@ -41,9 +40,7 @@ export function ListPage({
   onLoadMoreBefore,
   onLoadMoreAfter,
 }: Props): VNode {
-  const form = { payto_uri: "" };
 
-  const { i18n } = useTranslationContext();
   return (
     <section class="section is-main-section">
       <CardTable
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..690e3a2fc 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
@@ -19,13 +19,12 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { parsePaytoUri, PaytoType, PaytoUri, PaytoUriBitcoin, PaytoUriIBAN, 
PaytoUriTalerBank, PaytoUriUnknown, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { StateUpdater, useState } from "preact/hooks";
-import { MerchantBackend } from "../../../../declaration.js";
-import { parsePaytoUri, PaytoType, PaytoUri, PaytoUriBitcoin, PaytoUriIBAN, 
PaytoUriTalerBank, PaytoUriUnknown } from "@gnu-taler/taler-util";
 
-type Entity = MerchantBackend.BankAccounts.BankAccountEntry;
+type Entity = TalerMerchantApi.BankAccountEntry;
 
 interface Props {
   accounts: Entity[];
@@ -110,11 +109,6 @@ interface TableProps {
   onLoadMoreAfter?: () => void;
 }
 
-function toggleSelected<T>(id: T): (prev: T[]) => T[] {
-  return (prev: T[]): T[] =>
-    prev.indexOf(id) == -1 ? [...prev, id] : prev.filter((e) => e != id);
-}
-
 function Table({
   accounts,
   onLoadMoreAfter,
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..72efa08c9 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
@@ -19,7 +19,7 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
@@ -29,15 +29,13 @@ import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
-import { useInstanceOtpDevices, useOtpDeviceAPI } from 
"../../../../hooks/otp.js";
+import { useBankAccountAPI, useInstanceBankAccounts } from 
"../../../../hooks/bank.js";
 import { Notification } from "../../../../utils/types.js";
 import { ListPage } from "./ListPage.js";
-import { useBankAccountAPI, useInstanceBankAccounts } from 
"../../../../hooks/bank.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onCreate: () => void;
   onSelect: (id: string) => void;
@@ -91,7 +89,7 @@ export default function ListOtpDevices({
         onSelect={(e) => {
           onSelect(e.h_wire);
         }}
-        onDelete={(e: MerchantBackend.BankAccounts.BankAccountEntry) =>
+        onDelete={(e: TalerMerchantApi.BankAccountEntry) =>
           deleteBankAccount(e.h_wire)
             .then(() =>
               setNotif({
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..6dd264f29 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
@@ -19,6 +19,7 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
@@ -28,17 +29,16 @@ import {
   FormProvider,
 } from "../../../../components/form/FormProvider.js";
 import { Input } from "../../../../components/form/Input.js";
-import { MerchantBackend, WithId } from "../../../../declaration.js";
-import { InputSelector } from "../../../../components/form/InputSelector.js";
 import { InputPaytoForm } from "../../../../components/form/InputPaytoForm.js";
+import { InputSelector } from "../../../../components/form/InputSelector.js";
 import { undefinedIfEmpty } from "../../../../utils/table.js";
 
-type Entity = MerchantBackend.BankAccounts.BankAccountEntry
+type Entity = TalerMerchantApi.BankAccountEntry
   & WithId;
 
 const accountAuthType = ["unedit", "none", "basic"];
 interface Props {
-  onUpdate: (d: MerchantBackend.BankAccounts.AccountPatchDetails) => 
Promise<void>;
+  onUpdate: (d: TalerMerchantApi.AccountPatchDetails) => Promise<void>;
   onBack?: () => void;
   account: Entity;
 }
@@ -47,7 +47,7 @@ interface Props {
 export function UpdatePage({ account, onUpdate, onBack }: Props): VNode {
   const { i18n } = useTranslationContext();
 
-  const [state, setState] = 
useState<Partial<MerchantBackend.BankAccounts.AccountPatchDetails>>(account);
+  const [state, setState] = 
useState<Partial<TalerMerchantApi.AccountPatchDetails>>(account);
 
   // @ts-expect-error "unedit" is fine since is part of the accountAuthType 
values
   if (state.credit_facade_credentials?.type === "unedit") {
@@ -55,7 +55,7 @@ export function UpdatePage({ account, onUpdate, onBack }: 
Props): VNode {
     state.credit_facade_credentials = undefined
   }
 
-  const errors: FormErrors<MerchantBackend.BankAccounts.AccountPatchDetails> = 
{
+  const errors: FormErrors<TalerMerchantApi.AccountPatchDetails> = {
     credit_facade_url: !state.credit_facade_url ? undefined : 
!isValidURL(state.credit_facade_url) ? i18n.str`invalid url` : undefined,
     credit_facade_credentials: undefinedIfEmpty({
 
@@ -81,7 +81,7 @@ export function UpdatePage({ account, onUpdate, onBack }: 
Props): VNode {
 
     const credit_facade_url = !state.credit_facade_url ? undefined : new 
URL("/", state.credit_facade_url).href
 
-    const credit_facade_credentials: 
MerchantBackend.BankAccounts.FacadeCredentials | undefined =
+    const credit_facade_credentials: TalerMerchantApi.FacadeCredentials | 
undefined =
       credit_facade_url == undefined || state.credit_facade_credentials === 
undefined ? undefined :
         state.credit_facade_credentials.type === "basic" ? {
           type: "basic",
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..742d13b67 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
@@ -19,7 +19,7 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
@@ -29,19 +29,18 @@ import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend, WithId } from "../../../../declaration.js";
 import { useBankAccountAPI, useBankAccountDetails } from 
"../../../../hooks/bank.js";
 import { Notification } from "../../../../utils/types.js";
 import { UpdatePage } from "./UpdatePage.js";
 
-export type Entity = MerchantBackend.BankAccounts.AccountPatchDetails & WithId;
+export type Entity = TalerMerchantApi.AccountPatchDetails & WithId;
 
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
   bid: string;
 }
 export default function UpdateValidator({
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..3168c7cc4 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
@@ -24,17 +24,17 @@ import { h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { FormProvider } from "../../../components/form/FormProvider.js";
 import { Input } from "../../../components/form/Input.js";
-import { MerchantBackend } from "../../../declaration.js";
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 
-type Entity = MerchantBackend.Instances.InstanceReconfigurationMessage;
+type Entity = TalerMerchantApi.InstanceReconfigurationMessage;
 interface Props {
   onUpdate: () => void;
   onDelete: () => void;
-  selected: MerchantBackend.Instances.QueryInstancesResponse;
+  selected: TalerMerchantApi.QueryInstancesResponse;
 }
 
 function convert(
-  from: MerchantBackend.Instances.QueryInstancesResponse,
+  from: TalerMerchantApi.QueryInstancesResponse,
 ): Entity {
   const defaults = {
     default_wire_fee_amortization: 1,
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..b76abee30 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
@@ -18,15 +18,14 @@ import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../components/exception/loading.js";
 import { DeleteModal } from "../../../components/modal/index.js";
-import { useInstanceContext } from "../../../context/instance.js";
-import { MerchantBackend } from "../../../declaration.js";
 import { useInstanceAPI, useInstanceDetails } from 
"../../../hooks/instance.js";
 import { DetailPage } from "./DetailPage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerErrorDetail } from "@gnu-taler/taler-util";
+import { useSessionContext } from "../../../context/session.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
   onUpdate: () => void;
   onNotFound: () => VNode;
   onDelete: () => void;
@@ -39,7 +38,7 @@ export default function Detail({
   onDelete,
   onNotFound,
 }: Props): VNode {
-  const { id } = useInstanceContext();
+  const { state } = useSessionContext();
   const result = useInstanceDetails();
   const [deleting, setDeleting] = useState<boolean>(false);
 
@@ -69,7 +68,7 @@ export default function Detail({
       />
       {deleting && (
         <DeleteModal
-          element={{ name: result.data.name, id }}
+          element={{ name: result.data.name, id: state.instance }}
           onCancel={() => setDeleting(false)}
           onConfirm={async (): Promise<void> => {
             try {
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..6cd2d9491 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
@@ -19,8 +19,8 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { h, VNode, FunctionalComponent } from "preact";
-import { ConfigContextProvider } from "../../../context/config.js";
+import { MerchantApiProviderTesting } from "@gnu-taler/web-util/browser";
+import { FunctionalComponent, h } from "preact";
 import { DetailPage as TestedComponent } from "./DetailPage.js";
 
 export default {
@@ -37,19 +37,32 @@ function createExample<Props>(
   props: Partial<Props>,
 ) {
   const component = (args: any) => (
-    <ConfigContextProvider
+    <MerchantApiProviderTesting
       value={{
-        currency: "TESTKUDOS",
-        version: "1",
-        currencies: {
-          currency: "TESTKUDOS"
+        cancelRequest: () => {},
+        config: {
+          currency: "ARS",
+          version: "1",
+          currencies: {
+            "ASD": {
+              name: "testkudos",
+              alt_unit_names: {},
+              num_fractional_input_digits: 1,
+              num_fractional_normal_digits: 1,
+              num_fractional_trailing_zero_digits: 1,
+            }
+          },
+          exchanges: [],
+          name: "taler-merchant"
         },
-        exchanges: [],
-        name: "taler-merchant"
+        hints: [],
+        lib: {} as any,
+        onActivity: (() => {}) as any,
+        url: new URL("asdasd"),
       }}
     >
       <Internal {...(props as any)} />
-    </ConfigContextProvider>
+    </MerchantApiProviderTesting>
   );
   return { component, props };
 }
@@ -57,7 +70,7 @@ function createExample<Props>(
 export const Example = createExample(TestedComponent, {
   selected: {
     name: "name",
-    auth: { method: "external" },
+    auth: { type: "external" },
     address: {},
     user_type: "business",
     jurisdiction: {},
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..046636b4b 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
@@ -19,10 +19,9 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { h, VNode, FunctionalComponent } from "preact";
-import { ListPage as TestedComponent } from "./ListPage.js";
+import { PaytoString } from "@gnu-taler/taler-util";
 import * as tests from "@gnu-taler/web-util/testing";
-import { MerchantBackend } from "../../../../declaration.js";
+import { ListPage as TestedComponent } from "./ListPage.js";
 
 export default {
   title: "Pages/KYC/List",
@@ -40,19 +39,19 @@ export const Example = tests.createExample(TestedComponent, 
{
       {
         aml_status: 0,
         exchange_url: "http://exchange.taler";,
-        payto_uri: "payto://iban/de123123123",
+        payto_uri: "payto://iban/de123123123" as PaytoString,
         kyc_url: "http://exchange.taler/kyc";,
       },
       {
         aml_status: 1,
         exchange_url: "http://exchange.taler";,
-        payto_uri: "payto://iban/de123123123",
+        payto_uri: "payto://iban/de123123123" as PaytoString,
       },
       {
         aml_status: 2,
         exchange_url: "http://exchange.taler";,
-        payto_uri: "payto://iban/de123123123",
+        payto_uri: "payto://iban/de123123123" as PaytoString,
       },
     ],
-  } as MerchantBackend.KYC.AccountKycRedirects,
+  },
 });
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..3eeed1d7b 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
@@ -19,12 +19,12 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
-import { MerchantBackend } from "../../../../declaration.js";
 
 export interface Props {
-  status: MerchantBackend.KYC.AccountKycRedirects;
+  status: TalerMerchantApi.AccountKycRedirects;
 }
 
 export function ListPage({ status }: Props): VNode {
@@ -85,11 +85,11 @@ export function ListPage({ status }: Props): VNode {
   );
 }
 interface PendingTableProps {
-  entries: MerchantBackend.KYC.MerchantAccountKycRedirect[];
+  entries: TalerMerchantApi.MerchantAccountKycRedirect[];
 }
 
 interface TimedOutTableProps {
-  entries: MerchantBackend.KYC.ExchangeKycTimeout[];
+  entries: TalerMerchantApi.ExchangeKycTimeout[];
 }
 
 function PendingTable({ entries }: PendingTableProps): VNode {
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..555eb47b9 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
@@ -22,14 +22,13 @@
 import { ErrorType, HttpError } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { Loading } from "../../../../components/exception/loading.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useInstanceKYCDetails } from "../../../../hooks/instance.js";
 import { ListPage } from "./ListPage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerErrorDetail } from "@gnu-taler/taler-util";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
   onNotFound: () => VNode;
 }
 
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..041ec73e7 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
@@ -19,10 +19,20 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { AbsoluteTime, Amounts, Duration, TalerProtocolDuration } from 
"@gnu-taler/taler-util";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import {
+  AbsoluteTime,
+  AmountString,
+  Amounts,
+  Duration,
+  TalerMerchantApi,
+  TalerProtocolDuration,
+} from "@gnu-taler/taler-util";
+import {
+  useMerchantApiContext,
+  useTranslationContext,
+} from "@gnu-taler/web-util/browser";
 import { format, isFuture } from "date-fns";
-import { ComponentChildren, Fragment, VNode, h } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import {
   FormErrors,
@@ -39,18 +49,15 @@ import { InputToggle } from 
"../../../../components/form/InputToggle.js";
 import { InventoryProductForm } from 
"../../../../components/product/InventoryProductForm.js";
 import { NonInventoryProductFrom } from 
"../../../../components/product/NonInventoryProductForm.js";
 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 { OrderCreateSchema as schema } from "../../../../schemas/index.js";
+import { usePreference } from "../../../../hooks/preference.js";
 import { rate } from "../../../../utils/amount.js";
 import { undefinedIfEmpty } from "../../../../utils/table.js";
 
 interface Props {
-  onCreate: (d: MerchantBackend.Orders.PostOrderRequest) => void;
+  onCreate: (d: TalerMerchantApi.PostOrderRequest) => void;
   onBack?: () => void;
   instanceConfig: InstanceConfig;
-  instanceInventory: (MerchantBackend.Products.ProductDetail & WithId)[];
+  instanceInventory: (TalerMerchantApi.ProductDetail & WithId)[];
 }
 interface InstanceConfig {
   use_stefan: boolean;
@@ -58,9 +65,16 @@ interface InstanceConfig {
   default_wire_transfer_delay: TalerProtocolDuration;
 }
 
-function with_defaults(config: InstanceConfig, currency: string): 
Partial<Entity> {
-  const defaultPayDeadline = 
Duration.fromTalerProtocolDuration(config.default_pay_delay);
-  const defaultWireDeadline = 
Duration.fromTalerProtocolDuration(config.default_wire_transfer_delay);
+function with_defaults(
+  config: InstanceConfig,
+  _currency: string,
+): Partial<Entity> {
+  const defaultPayDeadline = Duration.fromTalerProtocolDuration(
+    config.default_pay_delay,
+  );
+  const defaultWireDeadline = Duration.fromTalerProtocolDuration(
+    config.default_wire_transfer_delay,
+  );
 
   return {
     inventoryProducts: {},
@@ -69,9 +83,9 @@ function with_defaults(config: InstanceConfig, currency: 
string): Partial<Entity
     payments: {
       max_fee: undefined,
       createToken: true,
-      pay_deadline: (defaultPayDeadline),
-      refund_deadline: (defaultPayDeadline),
-      wire_transfer_deadline: (defaultWireDeadline),
+      pay_deadline: defaultPayDeadline,
+      refund_deadline: defaultPayDeadline,
+      wire_transfer_deadline: defaultWireDeadline,
     },
     shipping: {},
     extra: {},
@@ -79,7 +93,7 @@ function with_defaults(config: InstanceConfig, currency: 
string): Partial<Entity
 }
 
 interface ProductAndQuantity {
-  product: MerchantBackend.Products.ProductDetail & WithId;
+  product: TalerMerchantApi.ProductDetail & WithId;
   quantity: number;
 }
 export interface ProductMap {
@@ -93,7 +107,7 @@ interface Pricing {
 }
 interface Shipping {
   delivery_date?: Date;
-  delivery_location?: MerchantBackend.Location;
+  delivery_location?: TalerMerchantApi.Location;
   fullfilment_url?: string;
 }
 interface Payments {
@@ -107,33 +121,24 @@ interface Payments {
 }
 interface Entity {
   inventoryProducts: ProductMap;
-  products: MerchantBackend.Product[];
+  products: TalerMerchantApi.Product[];
   pricing: Partial<Pricing>;
   payments: Partial<Payments>;
   shipping: Partial<Shipping>;
   extra: Record<string, string>;
 }
 
-const stringIsValidJSON = (value: string) => {
-  try {
-    JSON.parse(value.trim());
-    return true;
-  } catch {
-    return false;
-  }
-};
-
 export function CreatePage({
   onCreate,
   onBack,
   instanceConfig,
   instanceInventory,
 }: Props): VNode {
-  const config = useConfigContext();
-  const instance_default = with_defaults(instanceConfig, config.currency)
+  const { config } = useMerchantApiContext();
+  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 || {});
 
@@ -158,22 +163,25 @@ export function CreatePage({
       refund_deadline: !value.payments?.refund_deadline
         ? undefined
         : value.payments.pay_deadline &&
-          Duration.cmp(value.payments.refund_deadline, 
value.payments.pay_deadline) === -1
-          ? i18n.str`refund deadline cannot be before pay deadline`
-          : value.payments.wire_transfer_deadline &&
             Duration.cmp(
-              value.payments.wire_transfer_deadline,
               value.payments.refund_deadline,
+              value.payments.pay_deadline,
             ) === -1
+          ? i18n.str`refund deadline cannot be before pay deadline`
+          : value.payments.wire_transfer_deadline &&
+              Duration.cmp(
+                value.payments.wire_transfer_deadline,
+                value.payments.refund_deadline,
+              ) === -1
             ? i18n.str`wire transfer deadline cannot be before refund deadline`
             : undefined,
       pay_deadline: !value.payments?.pay_deadline
         ? i18n.str`required`
         : value.payments.wire_transfer_deadline &&
-          Duration.cmp(
-            value.payments.wire_transfer_deadline,
-            value.payments.pay_deadline,
-          ) === -1
+            Duration.cmp(
+              value.payments.wire_transfer_deadline,
+              value.payments.pay_deadline,
+            ) === -1
           ? i18n.str`wire transfer deadline cannot be before pay deadline`
           : undefined,
       wire_transfer_deadline: !value.payments?.wire_transfer_deadline
@@ -184,12 +192,11 @@ export function CreatePage({
         : !value.payments?.refund_deadline
           ? i18n.str`should have a refund deadline`
           : Duration.cmp(
-            value.payments.refund_deadline,
-            value.payments.auto_refund_deadline,
-          ) == -1
+                value.payments.refund_deadline,
+                value.payments.auto_refund_deadline,
+              ) == -1
             ? i18n.str`auto refund cannot be after refund deadline`
             : undefined,
-
     }),
     shipping: undefinedIfEmpty({
       delivery_date: !value.shipping?.delivery_date
@@ -208,27 +215,36 @@ export function CreatePage({
     if (!value.payments) return;
     if (!value.shipping) return;
 
-    const request: MerchantBackend.Orders.PostOrderRequest = {
+    const request: TalerMerchantApi.PostOrderRequest = {
       order: {
         amount: order.pricing.order_price,
         summary: order.pricing.summary,
         products: productList,
         extra: undefinedIfEmpty(value.extra),
-        pay_deadline: !value.payments.pay_deadline ?
-          i18n.str`required` :
-          
AbsoluteTime.toProtocolTimestamp(AbsoluteTime.addDuration(AbsoluteTime.now(), 
value.payments.pay_deadline))
-        ,// : undefined,
-        wire_transfer_deadline: value.payments.wire_transfer_deadline
-          ? 
AbsoluteTime.toProtocolTimestamp(AbsoluteTime.addDuration(AbsoluteTime.now(), 
value.payments.wire_transfer_deadline))
-          : undefined,
-        refund_deadline: value.payments.refund_deadline
-          ? 
AbsoluteTime.toProtocolTimestamp(AbsoluteTime.addDuration(AbsoluteTime.now(), 
value.payments.refund_deadline))
-          : undefined,
+        pay_deadline: AbsoluteTime.toProtocolTimestamp(
+          AbsoluteTime.addDuration(
+            AbsoluteTime.now(),
+            value.payments.pay_deadline!,
+          ),
+        ),
+        wire_transfer_deadline: AbsoluteTime.toProtocolTimestamp(
+          AbsoluteTime.addDuration(
+            AbsoluteTime.now(),
+            value.payments.wire_transfer_deadline!,
+          ),
+        ),
+        refund_deadline: AbsoluteTime.toProtocolTimestamp(
+          AbsoluteTime.addDuration(
+            AbsoluteTime.now(),
+            value.payments.refund_deadline!,
+          ),
+        ),
         auto_refund: value.payments.auto_refund_deadline
-          ? 
Duration.toTalerProtocolDuration(value.payments.auto_refund_deadline)
+          ? Duration.toTalerProtocolDuration(
+              value.payments.auto_refund_deadline,
+            )
           : undefined,
-        max_fee: value.payments.max_fee as string,
-
+        max_fee: value.payments.max_fee as AmountString,
         delivery_date: value.shipping.delivery_date
           ? { t_s: value.shipping.delivery_date.getTime() / 1000 }
           : undefined,
@@ -247,7 +263,7 @@ export function CreatePage({
   };
 
   const addProductToTheInventoryList = (
-    product: MerchantBackend.Products.ProductDetail & WithId,
+    product: TalerMerchantApi.ProductDetail & WithId,
     quantity: number,
   ) => {
     valueHandler((v) => {
@@ -265,7 +281,7 @@ export function CreatePage({
     });
   };
 
-  const addNewProduct = async (product: MerchantBackend.Product) => {
+  const addNewProduct = async (product: TalerMerchantApi.Product) => {
     return valueHandler((v) => {
       const products = v.products ? [...v.products, product] : [];
       return { ...v, products };
@@ -281,7 +297,7 @@ export function CreatePage({
   };
 
   const [editingProduct, setEditingProduct] = useState<
-    MerchantBackend.Product | undefined
+    TalerMerchantApi.Product | undefined
   >(undefined);
 
   const totalPriceInventory = inventoryList.reduce((prev, cur) => {
@@ -292,7 +308,7 @@ export function CreatePage({
   const totalPriceProducts = productList.reduce((prev, cur) => {
     if (!cur.price) return zero;
     const p = Amounts.parseOrThrow(cur.price);
-    return Amounts.add(prev, Amounts.mult(p, cur.quantity).amount).amount;
+    return Amounts.add(prev, Amounts.mult(p, cur.quantity ?? 0).amount).amount;
   }, zero);
 
   const hasProducts = inventoryList.length > 0 || productList.length > 0;
@@ -301,7 +317,7 @@ export function CreatePage({
   const totalAsString = Amounts.stringify(totalPrice.amount);
   const allProducts = productList.concat(inventoryList.map(asProduct));
 
-  const [newField, setNewField] = useState("")
+  const [newField, setNewField] = useState("");
 
   useEffect(() => {
     valueHandler((v) => {
@@ -321,44 +337,50 @@ export function CreatePage({
     totalPrice.amount,
   );
 
-  const minAgeByProducts = allProducts.reduce(
+  const minAgeByProducts = inventoryList.reduce(
     (cur, prev) =>
-      !prev.minimum_age || cur > prev.minimum_age ? cur : prev.minimum_age,
+      !prev.product.minimum_age || cur > prev.product.minimum_age ? cur : 
prev.product.minimum_age,
     0,
   );
 
   // if there is no default pay deadline
-  const noDefault_payDeadline = !instance_default.payments || 
!instance_default.payments.pay_deadline
+  const noDefault_payDeadline =
+    !instance_default.payments || !instance_default.payments.pay_deadline;
   // and there is no default wire deadline
-  const noDefault_wireDeadline = !instance_default.payments || 
!instance_default.payments.wire_transfer_deadline
+  const noDefault_wireDeadline =
+    !instance_default.payments ||
+    !instance_default.payments.wire_transfer_deadline;
   // user required to set the taler options
-  const requiresSomeTalerOptions = noDefault_payDeadline || 
noDefault_wireDeadline
-
+  const requiresSomeTalerOptions =
+    noDefault_payDeadline || noDefault_wireDeadline;
 
   return (
     <div>
-
       <section class="section is-main-section">
         <div class="tabs is-toggle is-fullwidth is-small">
           <ul>
-            <li class={!settings.advanceOrderMode ? "is-active" : ""} 
onClick={() => {
-              updateSettings({
-                ...settings,
-                advanceOrderMode: false
-              })
-            }}>
-              <a >
-                <span><i18n.Translate>Simple</i18n.Translate></span>
+            <li
+              class={!settings.advanceOrderMode ? "is-active" : ""}
+              onClick={() => {
+                updateSettings("advanceOrderMode", false);
+              }}
+            >
+              <a>
+                <span>
+                  <i18n.Translate>Simple</i18n.Translate>
+                </span>
               </a>
             </li>
-            <li class={settings.advanceOrderMode ? "is-active" : ""} 
onClick={() => {
-              updateSettings({
-                ...settings,
-                advanceOrderMode: true
-              })
-            }}>
-              <a >
-                <span><i18n.Translate>Advanced</i18n.Translate></span>
+            <li
+              class={settings.advanceOrderMode ? "is-active" : ""}
+              onClick={() => {
+                updateSettings("advanceOrderMode", true);
+              }}
+            >
+              <a>
+                <span>
+                  <i18n.Translate>Advanced</i18n.Translate>
+                </span>
               </a>
             </li>
           </ul>
@@ -386,7 +408,7 @@ export function CreatePage({
                 inventory={instanceInventory}
               />
 
-              {settings.advanceOrderMode &&
+              {settings.advanceOrderMode && (
                 <NonInventoryProductFrom
                   productToEdit={editingProduct}
                   onAddProduct={(p) => {
@@ -394,7 +416,7 @@ export function CreatePage({
                     return addNewProduct(p);
                   }}
                 />
-              }
+              )}
 
               {allProducts.length > 0 && (
                 <ProductList
@@ -437,8 +459,8 @@ export function CreatePage({
                       discountOrRise > 0 &&
                       (discountOrRise < 1
                         ? `discount of %${Math.round(
-                          (1 - discountOrRise) * 100,
-                        )}`
+                            (1 - discountOrRise) * 100,
+                          )}`
                         : `rise of %${Math.round((discountOrRise - 1) * 100)}`)
                     }
                     tooltip={i18n.str`Amount to be paid by the customer`}
@@ -459,7 +481,7 @@ export function CreatePage({
                 tooltip={i18n.str`Title of the order to be shown to the 
customer`}
               />
 
-              {settings.advanceOrderMode &&
+              {settings.advanceOrderMode && (
                 <InputGroup
                   name="shipping"
                   label={i18n.str`Shipping and Fulfillment`}
@@ -485,146 +507,201 @@ export function CreatePage({
                     tooltip={i18n.str`URL to which the user will be redirected 
after successful payment.`}
                   />
                 </InputGroup>
-              }
+              )}
 
-              {(settings.advanceOrderMode || requiresSomeTalerOptions) &&
+              {(settings.advanceOrderMode || requiresSomeTalerOptions) && (
                 <InputGroup
                   name="payments"
                   label={i18n.str`Taler payment options`}
                   tooltip={i18n.str`Override default Taler payment settings 
for this order`}
                 >
-                  {(settings.advanceOrderMode || noDefault_payDeadline) && 
<InputDuration
-                    name="payments.pay_deadline"
-                    label={i18n.str`Payment time`}
-                    help={<DeadlineHelp 
duration={value.payments?.pay_deadline} />}
-                    withForever
-                    withoutClear
-                    tooltip={i18n.str`Time for the customer to pay for the 
offer before it expires. Inventory products will be reserved until this 
deadline. Time start to run after the order is created.`}
-                    side={
-                      <span>
-                        <button class="button" onClick={() => {
-                          const c = {
-                            ...value,
-                            payments: {
-                              ...(value.payments ?? {}),
-                              pay_deadline: 
instance_default.payments?.pay_deadline
-                            }
-                          }
-                          valueHandler(c)
-                        }}>
-                          <i18n.Translate>default</i18n.Translate>
-                        </button>
-                      </span>
-                    }
-                  />}
-                  {settings.advanceOrderMode && <InputDuration
-                    name="payments.refund_deadline"
-                    label={i18n.str`Refund time`}
-                    help={<DeadlineHelp 
duration={value.payments?.refund_deadline} />}
-                    withForever
-                    withoutClear
-                    tooltip={i18n.str`Time while the order can be refunded by 
the merchant. Time starts after the order is created.`}
-                    side={
-                      <span>
-                        <button class="button" onClick={() => {
-                          valueHandler({
-                            ...value,
-                            payments: {
-                              ...(value.payments ?? {}),
-                              refund_deadline: 
instance_default.payments?.refund_deadline
-                            }
-                          })
-                        }}>
-                          <i18n.Translate>default</i18n.Translate>
-                        </button>
-                      </span>
-                    }
-                  />}
-                  {(settings.advanceOrderMode || noDefault_wireDeadline) && 
<InputDuration
-                    name="payments.wire_transfer_deadline"
-                    label={i18n.str`Wire transfer time`}
-                    help={<DeadlineHelp 
duration={value.payments?.wire_transfer_deadline} />}
-                    withoutClear
-                    withForever
-                    tooltip={i18n.str`Time for the exchange to make the wire 
transfer. Time starts after the order is created.`}
-                    side={
-                      <span>
-                        <button class="button" onClick={() => {
-                          valueHandler({
-                            ...value,
-                            payments: {
-                              ...(value.payments ?? {}),
-                              wire_transfer_deadline: 
instance_default.payments?.wire_transfer_deadline
-                            }
-                          })
-                        }}>
-                          <i18n.Translate>default</i18n.Translate>
-                        </button>
-                      </span>
-                    }
-                  />}
-                  {settings.advanceOrderMode && <InputDuration
-                    name="payments.auto_refund_deadline"
-                    label={i18n.str`Auto-refund time`}
-                    help={<DeadlineHelp 
duration={value.payments?.auto_refund_deadline} />}
-                    tooltip={i18n.str`Time until which the wallet will 
automatically check for refunds without user interaction.`}
-                    withForever
-                  />}
-
-                  {settings.advanceOrderMode && <InputCurrency
-                    name="payments.max_fee"
-                    label={i18n.str`Maximum fee`}
-                    tooltip={i18n.str`Maximum fees the merchant is willing to 
cover for this order. Higher deposit fees must be covered in full by the 
consumer.`}
-                  />}
-                  {settings.advanceOrderMode && <InputToggle
-                    name="payments.createToken"
-                    label={i18n.str`Create token`}
-                    tooltip={i18n.str`If the order ID is easy to guess the 
token will prevent user to steal orders from others.`}
-                  />}
-                  {settings.advanceOrderMode && <InputNumber
-                    name="payments.minimum_age"
-                    label={i18n.str`Minimum age required`}
-                    tooltip={i18n.str`Any value greater than 0 will limit the 
coins able be used to pay this contract. If empty the age restriction will be 
defined by the products`}
-                    help={
-                      minAgeByProducts > 0
-                        ? i18n.str`Min age defined by the producs is 
${minAgeByProducts}`
-                        : i18n.str`No product with age restriction in this 
order`
-                    }
-                  />}
+                  {(settings.advanceOrderMode || noDefault_payDeadline) && (
+                    <InputDuration
+                      name="payments.pay_deadline"
+                      label={i18n.str`Payment time`}
+                      help={
+                        <DeadlineHelp duration={value.payments?.pay_deadline} 
/>
+                      }
+                      withForever
+                      withoutClear
+                      tooltip={i18n.str`Time for the customer to pay for the 
offer before it expires. Inventory products will be reserved until this 
deadline. Time start to run after the order is created.`}
+                      side={
+                        <span>
+                          <button
+                            class="button"
+                            onClick={() => {
+                              const c = {
+                                ...value,
+                                payments: {
+                                  ...(value.payments ?? {}),
+                                  pay_deadline:
+                                    instance_default.payments?.pay_deadline,
+                                },
+                              };
+                              valueHandler(c);
+                            }}
+                          >
+                            <i18n.Translate>default</i18n.Translate>
+                          </button>
+                        </span>
+                      }
+                    />
+                  )}
+                  {settings.advanceOrderMode && (
+                    <InputDuration
+                      name="payments.refund_deadline"
+                      label={i18n.str`Refund time`}
+                      help={
+                        <DeadlineHelp
+                          duration={value.payments?.refund_deadline}
+                        />
+                      }
+                      withForever
+                      withoutClear
+                      tooltip={i18n.str`Time while the order can be refunded 
by the merchant. Time starts after the order is created.`}
+                      side={
+                        <span>
+                          <button
+                            class="button"
+                            onClick={() => {
+                              valueHandler({
+                                ...value,
+                                payments: {
+                                  ...(value.payments ?? {}),
+                                  refund_deadline:
+                                    instance_default.payments?.refund_deadline,
+                                },
+                              });
+                            }}
+                          >
+                            <i18n.Translate>default</i18n.Translate>
+                          </button>
+                        </span>
+                      }
+                    />
+                  )}
+                  {(settings.advanceOrderMode || noDefault_wireDeadline) && (
+                    <InputDuration
+                      name="payments.wire_transfer_deadline"
+                      label={i18n.str`Wire transfer time`}
+                      help={
+                        <DeadlineHelp
+                          duration={value.payments?.wire_transfer_deadline}
+                        />
+                      }
+                      withoutClear
+                      withForever
+                      tooltip={i18n.str`Time for the exchange to make the wire 
transfer. Time starts after the order is created.`}
+                      side={
+                        <span>
+                          <button
+                            class="button"
+                            onClick={() => {
+                              valueHandler({
+                                ...value,
+                                payments: {
+                                  ...(value.payments ?? {}),
+                                  wire_transfer_deadline:
+                                    instance_default.payments
+                                      ?.wire_transfer_deadline,
+                                },
+                              });
+                            }}
+                          >
+                            <i18n.Translate>default</i18n.Translate>
+                          </button>
+                        </span>
+                      }
+                    />
+                  )}
+                  {settings.advanceOrderMode && (
+                    <InputDuration
+                      name="payments.auto_refund_deadline"
+                      label={i18n.str`Auto-refund time`}
+                      help={
+                        <DeadlineHelp
+                          duration={value.payments?.auto_refund_deadline}
+                        />
+                      }
+                      tooltip={i18n.str`Time until which the wallet will 
automatically check for refunds without user interaction.`}
+                      withForever
+                    />
+                  )}
+
+                  {settings.advanceOrderMode && (
+                    <InputCurrency
+                      name="payments.max_fee"
+                      label={i18n.str`Maximum fee`}
+                      tooltip={i18n.str`Maximum fees the merchant is willing 
to cover for this order. Higher deposit fees must be covered in full by the 
consumer.`}
+                    />
+                  )}
+                  {settings.advanceOrderMode && (
+                    <InputToggle
+                      name="payments.createToken"
+                      label={i18n.str`Create token`}
+                      tooltip={i18n.str`If the order ID is easy to guess the 
token will prevent user to steal orders from others.`}
+                    />
+                  )}
+                  {settings.advanceOrderMode && (
+                    <InputNumber
+                      name="payments.minimum_age"
+                      label={i18n.str`Minimum age required`}
+                      tooltip={i18n.str`Any value greater than 0 will limit 
the coins able be used to pay this contract. If empty the age restriction will 
be defined by the products`}
+                      help={
+                        minAgeByProducts > 0
+                          ? i18n.str`Min age defined by the producs is 
${minAgeByProducts}`
+                          : i18n.str`No product with age restriction in this 
order`
+                      }
+                    />
+                  )}
                 </InputGroup>
-              }
+              )}
 
-              {settings.advanceOrderMode &&
+              {settings.advanceOrderMode && (
                 <InputGroup
                   name="extra"
                   label={i18n.str`Additional information`}
                   tooltip={i18n.str`Custom information to be included in the 
contract for this order.`}
                 >
-                  {Object.keys(value.extra ?? {}).map((key) => {
-
-                    return <Input
-                      name={`extra.${key}`}
-                      inputType="multiline"
-                      label={key}
-                      tooltip={i18n.str`You must enter a value in JavaScript 
Object Notation (JSON).`}
-                      side={
-                        <button class="button" onClick={(e) => {
-                          if (value.extra && value.extra[key] !== undefined) {
-                            console.log(value.extra)
-                            delete value.extra[key]
-                          }
-                          valueHandler({
-                            ...value,
-                          })
-                        }}>remove</button>
-                      }
-                    />
+                  {Object.keys(value.extra ?? {}).map((key, idx) => {
+                    return (
+                      <Input
+                        name={`extra.${key}`}
+                        key={String(idx)}
+                        inputType="multiline"
+                        label={key}
+                        tooltip={i18n.str`You must enter a value in JavaScript 
Object Notation (JSON).`}
+                        side={
+                          <button
+                            class="button"
+                            onClick={(e) => {
+                              if (
+                                value.extra &&
+                                value.extra[key] !== undefined
+                              ) {
+                                console.log(value.extra);
+                                delete value.extra[key];
+                              }
+                              valueHandler({
+                                ...value,
+                              });
+                              e.preventDefault();
+                            }}
+                          >
+                            remove
+                          </button>
+                        }
+                      />
+                    );
                   })}
                   <div class="field is-horizontal">
                     <div class="field-label is-normal">
                       <label class="label">
                         <i18n.Translate>Custom field name</i18n.Translate>
-                        <span class="icon has-tooltip-right" 
data-tooltip={"new extra field"}>
+                        <span
+                          class="icon has-tooltip-right"
+                          data-tooltip={"new extra field"}
+                        >
                           <i class="mdi mdi-information" />
                         </span>
                       </label>
@@ -632,23 +709,33 @@ export function CreatePage({
                     <div class="field-body is-flex-grow-3">
                       <div class="field">
                         <p class="control">
-                          <input class="input " value={newField} onChange={(e) 
=> setNewField(e.currentTarget.value)} />
+                          <input
+                            class="input "
+                            value={newField}
+                            onChange={(e) => 
setNewField(e.currentTarget.value)}
+                          />
                         </p>
                       </div>
                     </div>
-                    <button class="button" onClick={(e) => {
-                      setNewField("")
-                      valueHandler({
-                        ...value,
-                        extra: {
-                          ...(value.extra ?? {}),
-                          [newField]: ""
-                        }
-                      })
-                    }}>add</button>
+                    <button
+                      class="button"
+                      onClick={(e) => {
+                        setNewField("");
+                        valueHandler({
+                          ...value,
+                          extra: {
+                            ...(value.extra ?? {}),
+                            [newField]: "",
+                          },
+                        });
+                        e.preventDefault();
+                      }}
+                    >
+                      add
+                    </button>
                   </div>
                 </InputGroup>
-              }
+              )}
             </FormProvider>
 
             <div class="buttons is-right mt-5">
@@ -673,7 +760,7 @@ export function CreatePage({
   );
 }
 
-function asProduct(p: ProductAndQuantity): MerchantBackend.Product {
+function asProduct(p: ProductAndQuantity): TalerMerchantApi.Product {
   return {
     product_id: p.product.id,
     image: p.product.image,
@@ -682,24 +769,27 @@ function asProduct(p: ProductAndQuantity): 
MerchantBackend.Product {
     quantity: p.quantity,
     description: p.product.description,
     taxes: p.product.taxes,
-    minimum_age: p.product.minimum_age,
   };
 }
 
-
 function DeadlineHelp({ duration }: { duration?: Duration }): VNode {
   const { i18n } = useTranslationContext();
-  const [now, setNow] = useState(AbsoluteTime.now())
+  const [now, setNow] = useState(AbsoluteTime.now());
   useEffect(() => {
     const iid = setInterval(() => {
-      setNow(AbsoluteTime.now())
-    }, 60 * 1000)
+      setNow(AbsoluteTime.now());
+    }, 60 * 1000);
     return () => {
-      clearInterval(iid)
-    }
-  })
-  if (!duration) return <i18n.Translate>Disabled</i18n.Translate>
-  const when = AbsoluteTime.addDuration(now, duration)
-  if (when.t_ms === "never") return <i18n.Translate>No 
deadline</i18n.Translate>
-  return <i18n.Translate>Deadline at {format(when.t_ms, "dd/MM/yy 
HH:mm")}</i18n.Translate>
+      clearInterval(iid);
+    };
+  });
+  if (!duration) return <i18n.Translate>Disabled</i18n.Translate>;
+  const when = AbsoluteTime.addDuration(now, duration);
+  if (when.t_ms === "never")
+    return <i18n.Translate>No deadline</i18n.Translate>;
+  return (
+    <i18n.Translate>
+      Deadline at {format(when.t_ms, "dd/MM/yy HH:mm")}
+    </i18n.Translate>
+  );
 }
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..0f8618435 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
@@ -19,29 +19,28 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import { ErrorType, HttpError } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useInstanceDetails } from "../../../../hooks/instance.js";
 import { useOrderAPI } from "../../../../hooks/order.js";
 import { useInstanceProducts } from "../../../../hooks/product.js";
 import { Notification } from "../../../../utils/types.js";
 import { CreatePage } from "./CreatePage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
 
 export type Entity = {
-  request: MerchantBackend.Orders.PostOrderRequest;
-  response: MerchantBackend.Orders.PostOrderResponse;
+  request: TalerMerchantApi.PostOrderRequest;
+  response: TalerMerchantApi.PostOrderResponse;
 };
 interface Props {
   onBack?: () => void;
   onConfirm: (id: string) => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
 }
 export default function OrderCreate({
   onConfirm,
@@ -93,7 +92,7 @@ export default function OrderCreate({
 
       <CreatePage
         onBack={onBack}
-        onCreate={(request: MerchantBackend.Orders.PostOrderRequest) => {
+        onCreate={(request: TalerMerchantApi.PostOrderRequest) => {
           createOrder(request)
             .then((r) => {
               return onConfirm(r.data.order_id)
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..7d4877db9 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
@@ -19,9 +19,9 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { AmountString, TalerMerchantApi } from "@gnu-taler/taler-util";
 import { addDays } from "date-fns";
-import { h, VNode, FunctionalComponent } from "preact";
-import { MerchantBackend } from "../../../../declaration.js";
+import { FunctionalComponent, h } from "preact";
 import { DetailPage as TestedComponent } from "./DetailPage.js";
 
 export default {
@@ -42,14 +42,13 @@ function createExample<Props>(
   return r;
 }
 
-const defaultContractTerm = {
-  amount: "TESTKUDOS:10",
+const defaultContractTerm: TalerMerchantApi.ContractTerms = {
+  amount: "TESTKUDOS:10" as AmountString,
   timestamp: {
     t_s: new Date().getTime() / 1000,
   },
-  auditors: [],
   exchanges: [],
-  max_fee: "TESTKUDOS:1",
+  max_fee: "TESTKUDOS:1" as AmountString,
   merchant: {} as any,
   merchant_base_url: "http://merchant.url/";,
   order_id: "2021.165-03GDFC26Y1NNG",
@@ -66,7 +65,7 @@ const defaultContractTerm = {
   },
   wire_method: "x-taler-bank",
   h_wire: "asd",
-} as MerchantBackend.ContractTerms;
+};
 
 // contract_terms: defaultContracTerm,
 export const Claimed = createExample(TestedComponent, {
@@ -83,15 +82,16 @@ export const PaidNotRefundable = 
createExample(TestedComponent, {
     order_status: "paid",
     contract_terms: defaultContractTerm,
     refunded: false,
-    deposit_total: "TESTKUDOS:10",
-    exchange_ec: 0,
+    deposit_total: "TESTKUDOS:10" as AmountString,
+    exchange_code: 0,
     order_status_url: "http://merchant.backend/status";,
-    exchange_hc: 0,
-    refund_amount: "TESTKUDOS:0",
+    exchange_http_status: 0,
+    refund_amount: "TESTKUDOS:0" as AmountString,
     refund_details: [],
     refund_pending: false,
     wire_details: [],
     wired: false,
+    wire_reports: [],
   },
 });
 
@@ -106,12 +106,13 @@ export const PaidRefundable = 
createExample(TestedComponent, {
       },
     },
     refunded: false,
-    deposit_total: "TESTKUDOS:10",
-    exchange_ec: 0,
+    deposit_total: "TESTKUDOS:10" as AmountString,
+    exchange_code: 0,
     order_status_url: "http://merchant.backend/status";,
-    exchange_hc: 0,
-    refund_amount: "TESTKUDOS:0",
+    exchange_http_status: 0,
+    refund_amount: "TESTKUDOS:0" as AmountString,
     refund_details: [],
+    wire_reports: [],
     refund_pending: false,
     wire_details: [],
     wired: false,
@@ -128,6 +129,6 @@ export const Unpaid = createExample(TestedComponent, {
     },
     summary: "text summary",
     taler_pay_uri: "pay uri",
-    total_amount: "TESTKUDOS:10",
+    total_amount: "TESTKUDOS:10" as AmountString,
   },
 });
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..4ed78b002 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
@@ -19,7 +19,12 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { AmountJson, Amounts, stringifyRefundUri } from 
"@gnu-taler/taler-util";
+import {
+  AmountJson,
+  Amounts,
+  TalerMerchantApi,
+  stringifyRefundUri,
+} from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { format, formatDistance } from "date-fns";
 import { Fragment, VNode, h } from "preact";
@@ -33,28 +38,30 @@ 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 { useSessionContext } from "../../../../context/session.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";
 
-type Entity = MerchantBackend.Orders.MerchantOrderStatusResponse;
-type CT = MerchantBackend.ContractTerms;
+type Entity = TalerMerchantApi.MerchantOrderStatusResponse;
+type CT = TalerMerchantApi.ContractTerms;
 
 interface Props {
   onBack: () => void;
   selected: Entity;
   id: string;
-  onRefund: (id: string, value: MerchantBackend.Orders.RefundRequest) => void;
+  onRefund: (id: string, value: TalerMerchantApi.RefundRequest) => void;
 }
 
-type Paid = MerchantBackend.Orders.CheckPaymentPaidResponse & {
+type Paid = TalerMerchantApi.CheckPaymentPaidResponse & {
   refund_taken: string;
 };
-type Unpaid = MerchantBackend.Orders.CheckPaymentUnpaidResponse;
-type Claimed = MerchantBackend.Orders.CheckPaymentClaimedResponse;
+type Unpaid = TalerMerchantApi.CheckPaymentUnpaidResponse;
+type Claimed = TalerMerchantApi.CheckPaymentClaimedResponse;
 
 function ContractTerms({ value }: { value: CT }) {
   const { i18n } = useTranslationContext();
@@ -149,7 +156,7 @@ function ClaimedPage({
   order,
 }: {
   id: string;
-  order: MerchantBackend.Orders.CheckPaymentClaimedResponse;
+  order: TalerMerchantApi.CheckPaymentClaimedResponse;
 }) {
   const events: Event[] = [];
   if (order.contract_terms.timestamp.t_s !== "never") {
@@ -193,7 +200,7 @@ function ClaimedPage({
 
   const [value, valueHandler] = useState<Partial<Claimed>>(order);
   const { i18n } = useTranslationContext();
-  const [settings] = useSettings()
+  const [settings] = usePreference();
 
   return (
     <div>
@@ -237,10 +244,14 @@ function ClaimedPage({
                           <b>
                             <i18n.Translate>claimed at</i18n.Translate>:
                           </b>{" "}
-                          {format(
-                            new Date(order.contract_terms.timestamp.t_s * 
1000),
-                            datetimeFormatForSettings(settings)
-                          )}
+                          {order.contract_terms.timestamp.t_s === "never"
+                            ? "never"
+                            : format(
+                                new Date(
+                                  order.contract_terms.timestamp.t_s * 1000,
+                                ),
+                                datetimeFormatForSettings(settings),
+                              )}
                         </p>
                       </div>
                     </div>
@@ -311,7 +322,7 @@ function PaidPage({
   onRefund,
 }: {
   id: string;
-  order: MerchantBackend.Orders.CheckPaymentPaidResponse;
+  order: TalerMerchantApi.CheckPaymentPaidResponse;
   onRefund: (id: string) => void;
 }) {
   const events: Event[] = [];
@@ -365,8 +376,8 @@ function PaidPage({
   });
   if (order.wire_details && order.wire_details.length) {
     if (order.wire_details.length > 1) {
-      let last: MerchantBackend.Orders.TransactionWireTransfer | null = null;
-      let first: MerchantBackend.Orders.TransactionWireTransfer | null = null;
+      let last: TalerMerchantApi.TransactionWireTransfer | null = null;
+      let first: TalerMerchantApi.TransactionWireTransfer | null = null;
       let total: AmountJson | null = null;
 
       order.wire_details.forEach((w) => {
@@ -410,18 +421,22 @@ function PaidPage({
     }
   }
 
-  const now = new Date()
+  const now = new Date();
   const nextEvent = events.find((e) => {
-    return e.when.getTime() > now.getTime()
-  })
+    return e.when.getTime() > now.getTime();
+  });
 
   const [value, valueHandler] = useState<Partial<Paid>>(order);
-  const { url: backendURL } = useBackendContext()
+  const {
+    state: { backendUrl },
+  } = useSessionContext();
+
   const refundurl = stringifyRefundUri({
-    merchantBaseUrl: backendURL,
-    orderId: order.contract_terms.order_id
-  })
+    merchantBaseUrl: backendUrl,
+    orderId: order.contract_terms.order_id,
+  });
   const refundable =
+    order.contract_terms.refund_deadline.t_s !== "never" &&
     new Date().getTime() < order.contract_terms.refund_deadline.t_s * 1000;
   const { i18n } = useTranslationContext();
 
@@ -503,15 +518,16 @@ function PaidPage({
                           textOverflow: "ellipsis",
                         }}
                       >
-                        {nextEvent &&
+                        {nextEvent && (
                           <p>
-                            <i18n.Translate>Next event in </i18n.Translate> 
{formatDistance(
+                            <i18n.Translate>Next event in </i18n.Translate>{" 
"}
+                            {formatDistance(
                               nextEvent.when,
                               new Date(),
                               // "yyyy/MM/dd HH:mm:ss",
                             )}
                           </p>
-                        }
+                        )}
                       </div>
                     </div>
                   </div>
@@ -607,11 +623,11 @@ function UnpaidPage({
   order,
 }: {
   id: string;
-  order: MerchantBackend.Orders.CheckPaymentUnpaidResponse;
+  order: TalerMerchantApi.CheckPaymentUnpaidResponse;
 }) {
   const [value, valueHandler] = useState<Partial<Unpaid>>(order);
   const { i18n } = useTranslationContext();
-  const [settings] = useSettings()
+  const [settings] = usePreference();
   return (
     <div>
       <section class="hero is-hero-bar">
@@ -659,9 +675,9 @@ function UnpaidPage({
                     {order.creation_time.t_s === "never"
                       ? "never"
                       : format(
-                        new Date(order.creation_time.t_s * 1000),
-                        datetimeFormatForSettings(settings)
-                      )}
+                          new Date(order.creation_time.t_s * 1000),
+                          datetimeFormatForSettings(settings),
+                        )}
                   </p>
                 </div>
               </div>
@@ -764,7 +780,3 @@ export function DetailPage({ id, selected, onRefund, onBack 
}: Props): VNode {
     </Fragment>
   );
 }
-
-async function copyToClipboard(text: string) {
-  return navigator.clipboard.writeText(text);
-}
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..a7fe1801b 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
@@ -13,20 +13,19 @@
  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 { HttpStatusCode, TalerErrorDetail } from "@gnu-taler/taler-util";
 import {
-  useTranslationContext,
-  HttpError,
   ErrorType,
+  HttpError,
+  useTranslationContext,
 } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useOrderAPI, useOrderDetails } from "../../../../hooks/order.js";
 import { Notification } from "../../../../utils/types.js";
 import { DetailPage } from "./DetailPage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
 
 export interface Props {
   oid: string;
@@ -34,7 +33,7 @@ export interface Props {
   onBack: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
 }
 
 export default function Update({
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..5c9969689 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
@@ -19,8 +19,9 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { h, VNode, FunctionalComponent } from "preact";
+import { FunctionalComponent, h } from "preact";
 import { ListPage as TestedComponent } from "./ListPage.js";
+import { AmountString } from "@gnu-taler/taler-util";
 
 export default {
   title: "Pages/Order/List",
@@ -54,7 +55,7 @@ export const Example = createExample(TestedComponent, {
   orders: [
     {
       id: "123",
-      amount: "TESTKUDOS:10",
+      amount: "TESTKUDOS:10" as AmountString,
       paid: false,
       refundable: true,
       row_id: 1,
@@ -66,7 +67,7 @@ export const Example = createExample(TestedComponent, {
     },
     {
       id: "234",
-      amount: "TESTKUDOS:12",
+      amount: "TESTKUDOS:12" as AmountString,
       paid: true,
       refundable: true,
       row_id: 2,
@@ -79,7 +80,7 @@ export const Example = createExample(TestedComponent, {
     },
     {
       id: "456",
-      amount: "TESTKUDOS:1",
+      amount: "TESTKUDOS:1" as AmountString,
       paid: false,
       refundable: false,
       row_id: 3,
@@ -92,7 +93,7 @@ export const Example = createExample(TestedComponent, {
     },
     {
       id: "234",
-      amount: "TESTKUDOS:12",
+      amount: "TESTKUDOS:12" as AmountString,
       paid: false,
       refundable: false,
       row_id: 4,
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..7b88985dc 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
@@ -19,14 +19,14 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { format } from "date-fns";
-import { h, VNode, Fragment } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { DatePicker } from "../../../../components/picker/DatePicker.js";
-import { MerchantBackend, WithId } from "../../../../declaration.js";
+import { dateFormatForSettings, usePreference } from 
"../../../../hooks/preference.js";
 import { CardTable } from "./Table.js";
-import { dateFormatForSettings, useSettings } from 
"../../../../hooks/useSettings.js";
 
 export interface ListPageProps {
   onShowAll: () => void;
@@ -46,14 +46,14 @@ export interface ListPageProps {
   jumpToDate?: Date;
   onSelectDate: (date?: Date) => void;
 
-  orders: (MerchantBackend.Orders.OrderHistoryEntry & WithId)[];
+  orders: (TalerMerchantApi.OrderHistoryEntry & WithId)[];
   onLoadMoreBefore?: () => void;
   hasMoreBefore?: boolean;
   hasMoreAfter?: boolean;
   onLoadMoreAfter?: () => void;
 
-  onSelectOrder: (o: MerchantBackend.Orders.OrderHistoryEntry & WithId) => 
void;
-  onRefundOrder: (o: MerchantBackend.Orders.OrderHistoryEntry & WithId) => 
void;
+  onSelectOrder: (o: TalerMerchantApi.OrderHistoryEntry & WithId) => void;
+  onRefundOrder: (o: TalerMerchantApi.OrderHistoryEntry & WithId) => void;
   onCreate: () => 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..c3df81b87 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
@@ -19,10 +19,13 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { Amounts } from "@gnu-taler/taler-util";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import { Amounts, TalerMerchantApi } from "@gnu-taler/taler-util";
+import {
+  useMerchantApiContext,
+  useTranslationContext,
+} from "@gnu-taler/web-util/browser";
 import { format } from "date-fns";
-import { h, VNode } from "preact";
+import { VNode, h } from "preact";
 import { StateUpdater, useState } from "preact/hooks";
 import {
   FormErrors,
@@ -33,12 +36,13 @@ import { InputCurrency } from 
"../../../../components/form/InputCurrency.js";
 import { InputGroup } from "../../../../components/form/InputGroup.js";
 import { InputSelector } from "../../../../components/form/InputSelector.js";
 import { ConfirmModal } from "../../../../components/modal/index.js";
-import { useConfigContext } from "../../../../context/config.js";
-import { MerchantBackend, WithId } from "../../../../declaration.js";
+import {
+  datetimeFormatForSettings,
+  usePreference,
+} from "../../../../hooks/preference.js";
 import { mergeRefunds } from "../../../../utils/amount.js";
-import { datetimeFormatForSettings, useSettings } from 
"../../../../hooks/useSettings.js";
 
-type Entity = MerchantBackend.Orders.OrderHistoryEntry & WithId;
+type Entity = TalerMerchantApi.OrderHistoryEntry & WithId;
 interface Props {
   orders: Entity[];
   onRefund: (value: Entity) => void;
@@ -137,14 +141,11 @@ function Table({
   hasMoreBefore,
 }: TableProps): VNode {
   const { i18n } = useTranslationContext();
-  const [settings] = useSettings();
+  const [settings] = usePreference();
   return (
     <div class="table-container">
       {hasMoreBefore && (
-        <button
-          class="button is-fullwidth"
-          onClick={onLoadMoreBefore}
-        >
+        <button class="button is-fullwidth" onClick={onLoadMoreBefore}>
           <i18n.Translate>load newer orders</i18n.Translate>
         </button>
       )}
@@ -174,9 +175,9 @@ function Table({
                   {i.timestamp.t_s === "never"
                     ? "never"
                     : format(
-                      new Date(i.timestamp.t_s * 1000),
-                      datetimeFormatForSettings(settings),
-                    )}
+                        new Date(i.timestamp.t_s * 1000),
+                        datetimeFormatForSettings(settings),
+                      )}
                 </td>
                 <td
                   onClick={(): void => onSelect(i)}
@@ -218,10 +219,7 @@ function Table({
         </tbody>
       </table>
       {hasMoreAfter && (
-        <button
-          class="button is-fullwidth"
-          onClick={onLoadMoreAfter}
-        >
+        <button class="button is-fullwidth" onClick={onLoadMoreAfter}>
           <i18n.Translate>load older orders</i18n.Translate>
         </button>
       )}
@@ -249,8 +247,8 @@ function EmptyTable(): VNode {
 
 interface RefundModalProps {
   onCancel: () => void;
-  onConfirm: (value: MerchantBackend.Orders.RefundRequest) => void;
-  order: MerchantBackend.Orders.MerchantOrderStatusResponse;
+  onConfirm: (value: TalerMerchantApi.RefundRequest) => void;
+  order: TalerMerchantApi.MerchantOrderStatusResponse;
 }
 
 export function RefundModal({
@@ -260,7 +258,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>>({});
 
@@ -268,7 +266,7 @@ export function RefundModal({
     order.order_status === "paid" ? order.refund_details : []
   ).reduce(mergeRefunds, []);
 
-  const config = useConfigContext();
+  const { config } = useMerchantApiContext();
   const totalRefunded = refunds
     .map((r) => r.amount)
     .reduce(
@@ -362,9 +360,9 @@ export function RefundModal({
                           {r.timestamp.t_s === "never"
                             ? "never"
                             : format(
-                              new Date(r.timestamp.t_s * 1000),
-                              datetimeFormatForSettings(settings),
-                            )}
+                                new Date(r.timestamp.t_s * 1000),
+                                datetimeFormatForSettings(settings),
+                              )}
                         </td>
                         <td>{r.amount}</td>
                         <td>{r.reason}</td>
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..cd62685ca 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
@@ -19,16 +19,17 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
+import { JumpToElementById } from 
"../../../../components/form/JumpToElementById.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import {
   InstanceOrderFilter,
   useInstanceOrders,
@@ -38,12 +39,10 @@ import {
 import { Notification } from "../../../../utils/types.js";
 import { ListPage } from "./ListPage.js";
 import { RefundModal } from "./Table.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
-import { JumpToElementById } from 
"../../../../components/form/JumpToElementById.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onSelect: (id: string) => void;
   onCreate: () => void;
@@ -58,7 +57,7 @@ export default function OrderList({
 }: Props): VNode {
   const [filter, setFilter] = useState<InstanceOrderFilter>({ paid: "no" });
   const [orderToBeRefunded, setOrderToBeRefunded] = useState<
-    MerchantBackend.Orders.OrderHistoryEntry | undefined
+    TalerMerchantApi.OrderHistoryEntry | undefined
   >(undefined);
 
   const setNewDate = (date?: Date): void =>
@@ -186,10 +185,10 @@ export default function OrderList({
 interface RefundProps {
   id: string;
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onCancel: () => void;
-  onConfirm: (m: MerchantBackend.Orders.RefundRequest) => void;
+  onConfirm: (m: TalerMerchantApi.RefundRequest) => void;
 }
 
 function RefundModalForTable({
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..d5522c2d4 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
@@ -20,6 +20,7 @@
  */
 
 import {
+  TalerMerchantApi,
   isRfc3548Base32Charset,
   randomRfc3548Base32Key,
 } from "@gnu-taler/taler-util";
@@ -34,10 +35,8 @@ import {
 import { Input } from "../../../../components/form/Input.js";
 import { InputSelector } from "../../../../components/form/InputSelector.js";
 import { InputWithAddon } from "../../../../components/form/InputWithAddon.js";
-import { useBackendContext } from "../../../../context/backend.js";
-import { MerchantBackend } from "../../../../declaration.js";
 
-type Entity = MerchantBackend.OTP.OtpDeviceAddDetails;
+type Entity = TalerMerchantApi.OtpDeviceAddDetails;
 
 interface Props {
   onCreate: (d: Entity) => Promise<void>;
@@ -49,7 +48,6 @@ const algorithmsNames = ["off", "30s 8d TOTP-SHA1", "30s 8d 
eTOTP-SHA1"];
 
 export function CreatePage({ onCreate, onBack }: Props): VNode {
   const { i18n } = useTranslationContext();
-  const backend = useBackendContext();
 
   const [state, setState] = useState<Partial<Entity>>({});
 
@@ -114,7 +112,7 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
                 toStr={(v) => algorithmsNames[v]}
                 fromStr={(v) => Number(v)}
               />
-              {state.otp_algorithm && state.otp_algorithm > 0 ? (
+              {state.otp_algorithm  ? (
                 <Fragment>
                   <InputWithAddon<Entity>
                     expand
@@ -145,6 +143,7 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
                             ...s,
                             otp_key: randomRfc3548Base32Key(),
                           }));
+                          e.preventDefault();
                         }}
                       >
                         <i18n.Translate>random</i18n.Translate>
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..b1b4a0cf7 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
@@ -14,15 +14,14 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { Fragment, VNode, h } from "preact";
+import { VNode, h } from "preact";
 import { QR } from "../../../../components/exception/QR.js";
 import { CreatedSuccessfully as Template } from 
"../../../../components/notifications/CreatedSuccessfully.js";
-import { useInstanceContext } from "../../../../context/instance.js";
-import { MerchantBackend } from "../../../../declaration.js";
-import { useBackendContext } from "../../../../context/backend.js";
+import { useSessionContext } from "../../../../context/session.js";
 
-type Entity = MerchantBackend.OTP.OtpDeviceAddDetails;
+type Entity = TalerMerchantApi.OtpDeviceAddDetails;
 
 interface Props {
   entity: Entity;
@@ -34,11 +33,13 @@ export function CreatedSuccessfully({
   onConfirm,
 }: Props): VNode {
   const { i18n } = useTranslationContext();
-  const { url: backendURL } = useBackendContext()
-  const { id: instanceId } = useInstanceContext();
-  const issuer = new URL(backendURL).hostname;
-  const qrText = 
`otpauth://totp/${instanceId}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key}`;
-  const qrTextSafe = 
`otpauth://totp/${instanceId}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key.substring(0,
 6)}...`;
+  const {
+    state: { backendUrl },
+  } = useSessionContext();
+  const { state } = useSessionContext();
+  const issuer = backendUrl;
+  const qrText = 
`otpauth://totp/${state.instance}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key}`;
+  const qrTextSafe = 
`otpauth://totp/${state.instance}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key.substring(0,
 6)}...`;
 
   return (
     <Template onConfirm={onConfirm} >
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..e4501a053 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
@@ -19,18 +19,17 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
-import { useWebhookAPI } from "../../../../hooks/webhooks.js";
-import { Notification } from "../../../../utils/types.js";
-import { CreatePage } from "./CreatePage.js";
 import { useOtpDeviceAPI } from "../../../../hooks/otp.js";
+import { Notification } from "../../../../utils/types.js";
 import { CreatedSuccessfully } from "./CreatedSuccessfully.js";
+import { CreatePage } from "./CreatePage.js";
 
-export type Entity = MerchantBackend.OTP.OtpDeviceAddDetails;
+export type Entity = TalerMerchantApi.OtpDeviceAddDetails;
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
@@ -40,7 +39,7 @@ export default function CreateValidator({ onConfirm, onBack 
}: Props): VNode {
   const { createOtpDevice } = useOtpDeviceAPI();
   const [notif, setNotif] = useState<Notification | undefined>(undefined);
   const { i18n } = useTranslationContext();
-  const [created, setCreated] = 
useState<MerchantBackend.OTP.OtpDeviceAddDetails | null>(null)
+  const [created, setCreated] = useState<TalerMerchantApi.OtpDeviceAddDetails 
| null>(null)
 
   if (created) {
     return <CreatedSuccessfully entity={created} onConfirm={onConfirm} />
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..9022cc35b 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
@@ -19,18 +19,17 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { h, VNode } from "preact";
-import { MerchantBackend } from "../../../../declaration.js";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { CardTable } from "./Table.js";
 
 export interface Props {
-  devices: MerchantBackend.OTP.OtpDeviceEntry[];
+  devices: TalerMerchantApi.OtpDeviceEntry[];
   onLoadMoreBefore?: () => void;
   onLoadMoreAfter?: () => void;
   onCreate: () => void;
-  onDelete: (e: MerchantBackend.OTP.OtpDeviceEntry) => void;
-  onSelect: (e: MerchantBackend.OTP.OtpDeviceEntry) => void;
+  onDelete: (e: TalerMerchantApi.OtpDeviceEntry) => void;
+  onSelect: (e: TalerMerchantApi.OtpDeviceEntry) => void;
 }
 
 export function ListPage({
@@ -41,9 +40,7 @@ export function ListPage({
   onLoadMoreBefore,
   onLoadMoreAfter,
 }: Props): VNode {
-  const form = { payto_uri: "" };
 
-  const { i18n } = useTranslationContext();
   return (
     <section class="section is-main-section">
       <CardTable
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..7b1ccd4fc 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
@@ -19,12 +19,12 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { StateUpdater, useState } from "preact/hooks";
-import { MerchantBackend } from "../../../../declaration.js";
 
-type Entity = MerchantBackend.OTP.OtpDeviceEntry;
+type Entity = TalerMerchantApi.OtpDeviceEntry;
 
 interface Props {
   devices: Entity[];
@@ -109,11 +109,6 @@ interface TableProps {
   onLoadMoreAfter?: () => void;
 }
 
-function toggleSelected<T>(id: T): (prev: T[]) => T[] {
-  return (prev: T[]): T[] =>
-    prev.indexOf(id) == -1 ? [...prev, id] : prev.filter((e) => e != id);
-}
-
 function Table({
   instances,
   onLoadMoreAfter,
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..7fd827956 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
@@ -19,7 +19,7 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
@@ -29,14 +29,13 @@ import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useInstanceOtpDevices, useOtpDeviceAPI } from 
"../../../../hooks/otp.js";
 import { Notification } from "../../../../utils/types.js";
 import { ListPage } from "./ListPage.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onCreate: () => void;
   onSelect: (id: string) => void;
@@ -84,7 +83,7 @@ export default function ListOtpDevices({
         onSelect={(e) => {
           onSelect(e.otp_device_id);
         }}
-        onDelete={(e: MerchantBackend.OTP.OtpDeviceEntry) =>
+        onDelete={(e: TalerMerchantApi.OtpDeviceEntry) =>
           deleteOtpDevice(e.otp_device_id)
             .then(() =>
               setNotif({
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..35d67cbc6 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
@@ -19,7 +19,7 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { randomRfc3548Base32Key } from "@gnu-taler/taler-util";
+import { randomRfc3548Base32Key, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
@@ -31,9 +31,8 @@ import {
 import { Input } from "../../../../components/form/Input.js";
 import { InputSelector } from "../../../../components/form/InputSelector.js";
 import { InputWithAddon } from "../../../../components/form/InputWithAddon.js";
-import { MerchantBackend, WithId } from "../../../../declaration.js";
 
-type Entity = MerchantBackend.OTP.OtpDevicePatchDetails & WithId;
+type Entity = TalerMerchantApi.OtpDevicePatchDetails & WithId;
 
 interface Props {
   onUpdate: (d: Entity) => Promise<void>;
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..a824c6936 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
@@ -19,30 +19,29 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend, WithId } from "../../../../declaration.js";
-import { Notification } from "../../../../utils/types.js";
-import { UpdatePage } from "./UpdatePage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
 import { useOtpDeviceAPI, useOtpDeviceDetails } from 
"../../../../hooks/otp.js";
+import { Notification } from "../../../../utils/types.js";
 import { CreatedSuccessfully } from "../create/CreatedSuccessfully.js";
+import { UpdatePage } from "./UpdatePage.js";
 
-export type Entity = MerchantBackend.OTP.OtpDevicePatchDetails & WithId;
+export type Entity = TalerMerchantApi.OtpDevicePatchDetails & WithId;
 
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
   vid: string;
 }
 export default function UpdateValidator({
@@ -56,7 +55,7 @@ export default function UpdateValidator({
   const { updateOtpDevice } = useOtpDeviceAPI();
   const result = useOtpDeviceDetails(vid);
   const [notif, setNotif] = useState<Notification | undefined>(undefined);
-  const [keyUpdated, setKeyUpdated] = 
useState<MerchantBackend.OTP.OtpDeviceAddDetails | null>(null)
+  const [keyUpdated, setKeyUpdated] = 
useState<TalerMerchantApi.OtpDeviceAddDetails | null>(null)
 
   const { i18n } = useTranslationContext();
 
@@ -87,7 +86,7 @@ export default function UpdateValidator({
           id: vid,
           otp_algorithm: result.data.otp_algorithm,
           otp_device_description: result.data.device_description,
-          otp_key: undefined,
+          otp_key: "",
           otp_ctr: result.data.otp_ctr
         }}
         onBack={onBack}
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..64b174f64 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
@@ -19,14 +19,14 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { AsyncButton } from "../../../../components/exception/AsyncButton.js";
 import { ProductForm } from "../../../../components/product/ProductForm.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useListener } from "../../../../hooks/listener.js";
 
-type Entity = MerchantBackend.Products.ProductAddDetail & {
+type Entity = TalerMerchantApi.ProductAddDetail & {
   product_id: string;
 };
 
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..9935a9625 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
@@ -19,16 +19,16 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useProductAPI } from "../../../../hooks/product.js";
 import { Notification } from "../../../../utils/types.js";
 import { CreatePage } from "./CreatePage.js";
 
-export type Entity = MerchantBackend.Products.ProductAddDetail;
+export type Entity = TalerMerchantApi.ProductAddDetail;
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
@@ -43,7 +43,7 @@ export default function CreateProduct({ onConfirm, onBack }: 
Props): VNode {
       <NotificationCard notification={notif} />
       <CreatePage
         onBack={onBack}
-        onCreate={(request: MerchantBackend.Products.ProductAddDetail) => {
+        onCreate={(request: TalerMerchantApi.ProductAddDetail) => {
           return createProduct(request)
             .then(() => onConfirm())
             .catch((error) => {
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..580a92cdc 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
@@ -19,7 +19,8 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { h, VNode, FunctionalComponent } from "preact";
+import { AmountString } from "@gnu-taler/taler-util";
+import { FunctionalComponent, h } from "preact";
 import { CardTable as TestedComponent } from "./Table.js";
 
 export default {
@@ -49,7 +50,7 @@ export const Example = createExample(TestedComponent, {
       description: "description1",
       description_i18n: {} as any,
       image: "",
-      price: "TESTKUDOS:10",
+      price: "TESTKUDOS:10" as AmountString,
       taxes: [],
       total_lost: 10,
       total_sold: 5,
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..265146c01 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
@@ -19,10 +19,10 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { Amounts } from "@gnu-taler/taler-util";
+import { AmountString, Amounts, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { format } from "date-fns";
-import { ComponentChildren, Fragment, h, VNode } from "preact";
+import { ComponentChildren, Fragment, VNode, h } from "preact";
 import { StateUpdater, useState } from "preact/hooks";
 import emptyImage from "../../../../assets/empty.png";
 import {
@@ -31,10 +31,9 @@ import {
 } from "../../../../components/form/FormProvider.js";
 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;
+type Entity = TalerMerchantApi.ProductDetail & WithId;
 
 interface Props {
   instances: Entity[];
@@ -42,7 +41,7 @@ interface Props {
   onSelect: (product: Entity) => void;
   onUpdate: (
     id: string,
-    data: MerchantBackend.Products.ProductPatchDetail,
+    data: TalerMerchantApi.ProductPatchDetail,
   ) => Promise<void>;
   onCreate: () => void;
   selected?: boolean;
@@ -108,7 +107,7 @@ interface TableProps {
   onSelect: (id: Entity) => void;
   onUpdate: (
     id: string,
-    data: MerchantBackend.Products.ProductPatchDetail,
+    data: TalerMerchantApi.ProductPatchDetail,
   ) => Promise<void>;
   onDelete: (id: Entity) => void;
   rowSelectionHandler: StateUpdater<string | undefined>;
@@ -123,7 +122,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">
@@ -305,7 +304,7 @@ function Table({
 interface FastProductUpdateFormProps {
   product: Entity;
   onUpdate: (
-    data: MerchantBackend.Products.ProductPatchDetail,
+    data: TalerMerchantApi.ProductPatchDetail,
   ) => Promise<void>;
   onCancel: () => void;
 }
@@ -361,7 +360,7 @@ function FastProductWithInfiniteStockUpdateForm({
               onClick={() =>
                 onUpdate({
                   ...product,
-                  price: value.price,
+                  price: value.price as AmountString,
                 })
               }
             >
@@ -446,7 +445,7 @@ function FastProductWithManagedStockUpdateForm({
                 ...product,
                 total_stock: product.total_stock + value.incoming,
                 total_lost: product.total_lost + value.lost,
-                price: value.price,
+                price: value.price as AmountString,
               })
             }
           >
@@ -491,6 +490,6 @@ function difference(price: string, tax: number) {
   ps[1] = `${p - tax}`;
   return ps.join(":");
 }
-function sum(taxes: MerchantBackend.Tax[]) {
+function sum(taxes: TalerMerchantApi.Tax[]) {
   return taxes.reduce((p, c) => p + parseInt(c.tax.split(":")[1], 10), 0);
 }
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..1017a9334 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
@@ -19,32 +19,31 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
-import { h, VNode } from "preact";
+import { VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
+import { JumpToElementById } from 
"../../../../components/form/JumpToElementById.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend, WithId } from "../../../../declaration.js";
+import { ConfirmModal } from "../../../../components/modal/index.js";
 import {
   useInstanceProducts,
   useProductAPI,
 } from "../../../../hooks/product.js";
 import { Notification } from "../../../../utils/types.js";
 import { CardTable } from "./Table.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
-import { ConfirmModal, DeleteModal } from 
"../../../../components/modal/index.js";
-import { JumpToElementById } from 
"../../../../components/form/JumpToElementById.js";
 
 interface Props {
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
   onCreate: () => void;
   onSelect: (id: string) => void;
-  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
 }
 export default function ProductList({
   onUnauthorized,
@@ -56,7 +55,7 @@ export default function ProductList({
   const result = useInstanceProducts();
   const { deleteProduct, updateProduct, getProduct } = useProductAPI();
   const [deleting, setDeleting] =
-    useState<MerchantBackend.Products.ProductDetail & WithId | null>(null);
+    useState<TalerMerchantApi.ProductDetail & WithId | null>(null);
   const [notif, setNotif] = useState<Notification | undefined>(undefined);
 
   const { i18n } = useTranslationContext();
@@ -107,7 +106,7 @@ export default function ProductList({
             )
         }
         onSelect={(product) => onSelect(product.id)}
-        onDelete={(prod: MerchantBackend.Products.ProductDetail & WithId) =>
+        onDelete={(prod: TalerMerchantApi.ProductDetail & WithId) =>
           setDeleting(prod)
         }
       />
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..7aa93b186 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
@@ -19,7 +19,8 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { h, VNode, FunctionalComponent } from "preact";
+import { AmountString } from "@gnu-taler/taler-util";
+import { FunctionalComponent, h } from "preact";
 import { UpdatePage as TestedComponent } from "./UpdatePage.js";
 
 export default {
@@ -46,7 +47,7 @@ export const WithManagedStock = 
createExample(TestedComponent, {
     description: "description1",
     description_i18n: {} as any,
     image: "",
-    price: "TESTKUDOS:10",
+    price: "TESTKUDOS:10" as AmountString,
     taxes: [],
     total_lost: 10,
     total_sold: 5,
@@ -62,7 +63,7 @@ export const WithInfiniteStock = 
createExample(TestedComponent, {
     description: "description1",
     description_i18n: {} as any,
     image: "",
-    price: "TESTKUDOS:10",
+    price: "TESTKUDOS:10" as AmountString,
     taxes: [],
     total_lost: 10,
     total_sold: 5,
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..5395ae40f 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
@@ -19,14 +19,14 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { AsyncButton } from "../../../../components/exception/AsyncButton.js";
 import { ProductForm } from "../../../../components/product/ProductForm.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useListener } from "../../../../hooks/listener.js";
 
-type Entity = MerchantBackend.Products.ProductDetail & { product_id: string };
+type Entity = TalerMerchantApi.ProductDetail & { product_id: string };
 
 interface Props {
   onUpdate: (d: Entity) => Promise<void>;
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..842462c12 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
@@ -19,28 +19,27 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useProductAPI, useProductDetails } from 
"../../../../hooks/product.js";
 import { Notification } from "../../../../utils/types.js";
 import { UpdatePage } from "./UpdatePage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
 
-export type Entity = MerchantBackend.Products.ProductAddDetail;
+export type Entity = TalerMerchantApi.ProductAddDetail;
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
   pid: string;
 }
 export default function UpdateProduct({
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..31e525226 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
@@ -23,11 +23,13 @@ import {
   AmountString,
   Amounts,
   Duration,
-  MerchantTemplateContractDetails,
+  TalerMerchantApi,
   assertUnreachable,
 } from "@gnu-taler/taler-util";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { Fragment, VNode, h } from "preact";
+import {
+  useTranslationContext
+} from "@gnu-taler/web-util/browser";
+import { VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { AsyncButton } from "../../../../components/exception/AsyncButton.js";
 import {
@@ -39,12 +41,10 @@ import { InputCurrency } from 
"../../../../components/form/InputCurrency.js";
 import { InputDuration } from "../../../../components/form/InputDuration.js";
 import { InputNumber } from "../../../../components/form/InputNumber.js";
 import { InputSearchOnList } from 
"../../../../components/form/InputSearchOnList.js";
+import { InputTab } from "../../../../components/form/InputTab.js";
 import { InputWithAddon } from "../../../../components/form/InputWithAddon.js";
-import { useBackendContext } from "../../../../context/backend.js";
-import { MerchantBackend } from "../../../../declaration.js";
+import { useSessionContext } from "../../../../context/session.js";
 import { useInstanceOtpDevices } from "../../../../hooks/otp.js";
-import { undefinedIfEmpty } from "../../../../utils/table.js";
-import { InputTab } from "../../../../components/form/InputTab.js";
 
 enum Steps {
   BOTH_FIXED,
@@ -53,27 +53,29 @@ enum Steps {
   NON_FIXED,
 }
 
-// type Entity = MerchantBackend.Template.TemplateAddDetails & { type: Steps };
+// type Entity = TalerMerchantApi.TemplateAddDetails & { type: Steps };
 type Entity = {
-  id?: string,
-  description?: string,
-  otpId?: string,
-  summary?: string,
-  amount?: AmountString,
-  minimum_age?: number,
-  pay_duration?: Duration,
-  type: Steps,
+  id?: string;
+  description?: string;
+  otpId?: string;
+  summary?: string;
+  amount?: AmountString;
+  minimum_age?: number;
+  pay_duration?: Duration;
+  type: Steps;
 };
 
 interface Props {
-  onCreate: (d: MerchantBackend.Template.TemplateAddDetails) => Promise<void>;
+  onCreate: (d: TalerMerchantApi.TemplateAddDetails) => Promise<void>;
   onBack?: () => void;
 }
 
 export function CreatePage({ onCreate, onBack }: Props): VNode {
   const { i18n } = useTranslationContext();
-  const { url: backendURL } = useBackendContext()
-  const devices = useInstanceOtpDevices()
+  const {
+    state: { backendUrl },
+  } = useSessionContext();
+  const devices = useInstanceOtpDevices();
 
   const [state, setState] = useState<Partial<Entity>>({
     minimum_age: 0,
@@ -83,9 +85,7 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
     type: Steps.NON_FIXED,
   });
 
-  const parsedPrice = !state.amount
-    ? undefined
-    : Amounts.parse(state.amount);
+  const parsedPrice = !state.amount ? undefined : Amounts.parse(state.amount);
 
   const errors: FormErrors<Entity> = {
     id: !state.id
@@ -93,10 +93,10 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
       : !/[a-zA-Z0-9]*/.test(state.id)
         ? i18n.str`no valid. only characters and numbers`
         : undefined,
-    description: !state.description
-      ? i18n.str`should not be empty`
-      : undefined,
-    amount: !(state.type === Steps.FIXED_PRICE || state.type === 
Steps.BOTH_FIXED)
+    description: !state.description ? i18n.str`should not be empty` : 
undefined,
+    amount: !(
+      state.type === Steps.FIXED_PRICE || state.type === Steps.BOTH_FIXED
+    )
       ? undefined
       : !state.amount
         ? i18n.str`required`
@@ -105,7 +105,9 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
           : Amounts.isZero(parsedPrice)
             ? i18n.str`must be greater than 0`
             : undefined,
-    summary: !(state.type === Steps.FIXED_SUMMARY || state.type === 
Steps.BOTH_FIXED)
+    summary: !(
+      state.type === Steps.FIXED_SUMMARY || state.type === Steps.BOTH_FIXED
+    )
       ? undefined
       : !state.summary
         ? i18n.str`required`
@@ -130,55 +132,60 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
   const submitForm = () => {
     if (hasErrors || state.type === undefined) return Promise.reject();
     switch (state.type) {
-      case Steps.FIXED_PRICE: return onCreate({
-        template_id: state.id!,
-        template_description: state.description!,
-        template_contract: {
-          minimum_age: state.minimum_age!,
-          pay_duration: Duration.toTalerProtocolDuration(state.pay_duration!),
-          amount: state.amount!,
-          // summary: state.summary,
-        },
-        otp_id: state.otpId!
-      })
-      case Steps.FIXED_SUMMARY: return onCreate({
-        template_id: state.id!,
-        template_description: state.description!,
-        template_contract: {
-          minimum_age: state.minimum_age!,
-          pay_duration: Duration.toTalerProtocolDuration(state.pay_duration!),
-          // amount: state.amount!,
-          summary: state.summary,
-        },
-        otp_id: state.otpId!,
-      })
-      case Steps.NON_FIXED: return onCreate({
-        template_id: state.id!,
-        template_description: state.description!,
-        template_contract: {
-          minimum_age: state.minimum_age!,
-          pay_duration: Duration.toTalerProtocolDuration(state.pay_duration!),
-          // amount: state.amount!,
-          // summary: state.summary,
-        },
-        otp_id: state.otpId!,
-      })
-      case Steps.BOTH_FIXED: return onCreate({
-        template_id: state.id!,
-        template_description: state.description!,
-        template_contract: {
-          minimum_age: state.minimum_age!,
-          pay_duration: Duration.toTalerProtocolDuration(state.pay_duration!),
-          amount: state.amount!,
-          summary: state.summary,
-        },
-        otp_id: state.otpId!,
-      })
-      default: assertUnreachable(state.type)
+      case Steps.FIXED_PRICE:
+        return onCreate({
+          template_id: state.id!,
+          template_description: state.description!,
+          template_contract: {
+            minimum_age: state.minimum_age!,
+            pay_duration: 
Duration.toTalerProtocolDuration(state.pay_duration!),
+            amount: state.amount!,
+            // summary: state.summary,
+          },
+          otp_id: state.otpId!,
+        });
+      case Steps.FIXED_SUMMARY:
+        return onCreate({
+          template_id: state.id!,
+          template_description: state.description!,
+          template_contract: {
+            minimum_age: state.minimum_age!,
+            pay_duration: 
Duration.toTalerProtocolDuration(state.pay_duration!),
+            // amount: state.amount!,
+            summary: state.summary,
+          },
+          otp_id: state.otpId!,
+        });
+      case Steps.NON_FIXED:
+        return onCreate({
+          template_id: state.id!,
+          template_description: state.description!,
+          template_contract: {
+            minimum_age: state.minimum_age!,
+            pay_duration: 
Duration.toTalerProtocolDuration(state.pay_duration!),
+            // amount: state.amount!,
+            // summary: state.summary,
+          },
+          otp_id: state.otpId!,
+        });
+      case Steps.BOTH_FIXED:
+        return onCreate({
+          template_id: state.id!,
+          template_description: state.description!,
+          template_contract: {
+            minimum_age: state.minimum_age!,
+            pay_duration: 
Duration.toTalerProtocolDuration(state.pay_duration!),
+            amount: state.amount!,
+            summary: state.summary,
+          },
+          otp_id: state.otpId!,
+        });
+      default:
+        assertUnreachable(state.type);
       // return onCreate(state);
-    };
-  }
-  const deviceList = !devices.ok ? [] : devices.data.otp_devices
+    }
+  };
+  const deviceList = !devices.ok ? [] : devices.data.otp_devices;
 
   return (
     <div>
@@ -193,7 +200,7 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
             >
               <InputWithAddon<Entity>
                 name="id"
-                help={`${backendURL}/templates/${state.id ?? ""}`}
+                help={new URL(`templates/${state.id ?? ""}`, backendUrl).href}
                 label={i18n.str`Identifier`}
                 tooltip={i18n.str`Name of the template in URLs.`}
               />
@@ -207,12 +214,16 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
                 name="type"
                 label={i18n.str`Type`}
                 help={(() => {
-                  if (state.type === undefined) return ""
+                  if (state.type === undefined) return "";
                   switch (state.type) {
-                    case Steps.NON_FIXED: return i18n.str`User will be able to 
input price and summary before payment.`
-                    case Steps.FIXED_PRICE: return i18n.str`User will be able 
to add a summary before payment.`
-                    case Steps.FIXED_SUMMARY: return i18n.str`User will be 
able to set the price before payment.`
-                    case Steps.BOTH_FIXED: return i18n.str`User will not be 
able to change the price or the summary.`
+                    case Steps.NON_FIXED:
+                      return i18n.str`User will be able to input price and 
summary before payment.`;
+                    case Steps.FIXED_PRICE:
+                      return i18n.str`User will be able to add a summary 
before payment.`;
+                    case Steps.FIXED_SUMMARY:
+                      return i18n.str`User will be able to set the price 
before payment.`;
+                    case Steps.BOTH_FIXED:
+                      return i18n.str`User will not be able to change the 
price or the summary.`;
                   }
                 })()}
                 tooltip={i18n.str`Define what the user be allowed to modify`}
@@ -224,28 +235,34 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
                 ]}
                 toStr={(v: Steps): string => {
                   switch (v) {
-                    case Steps.NON_FIXED: return i18n.str`Simple`
-                    case Steps.FIXED_PRICE: return i18n.str`With price`
-                    case Steps.FIXED_SUMMARY: return i18n.str`With summary`
-                    case Steps.BOTH_FIXED: return i18n.str`With price and 
summary`
+                    case Steps.NON_FIXED:
+                      return i18n.str`Simple`;
+                    case Steps.FIXED_PRICE:
+                      return i18n.str`With price`;
+                    case Steps.FIXED_SUMMARY:
+                      return i18n.str`With summary`;
+                    case Steps.BOTH_FIXED:
+                      return i18n.str`With price and summary`;
                   }
                 }}
               />
-              {state.type === Steps.BOTH_FIXED || state.type === 
Steps.FIXED_SUMMARY ?
+              {state.type === Steps.BOTH_FIXED ||
+              state.type === Steps.FIXED_SUMMARY ? (
                 <Input<Entity>
                   name="summary"
                   inputType="multiline"
                   label={i18n.str`Fixed summary`}
                   tooltip={i18n.str`If specified, this template will create 
order with the same summary`}
                 />
-                : undefined}
-              {state.type === Steps.BOTH_FIXED || state.type === 
Steps.FIXED_PRICE ?
+              ) : undefined}
+              {state.type === Steps.BOTH_FIXED ||
+              state.type === Steps.FIXED_PRICE ? (
                 <InputCurrency<Entity>
                   name="amount"
                   label={i18n.str`Fixed price`}
                   tooltip={i18n.str`If specified, this template will create 
order with the same price`}
                 />
-                : undefined}
+              ) : undefined}
               <InputNumber<Entity>
                 name="minimum_age"
                 label={i18n.str`Minimum age`}
@@ -262,28 +279,29 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
                 name="otpId"
                 label={i18n.str`OTP device`}
                 readonly
-                side={<button
-                  class="button is-danger"
-                  data-tooltip={i18n.str`without otp device`}
-                  onClick={(): void => {
-                    setState((v) => ({ ...v, otpId: undefined }));
-                  }}
-                >
-                  <span>
-                    <i18n.Translate>remove</i18n.Translate>
-                  </span>
-                </button>}
+                side={
+                  <button
+                    class="button is-danger"
+                    data-tooltip={i18n.str`without otp device`}
+                    onClick={(): void => {
+                      setState((v) => ({ ...v, otpId: undefined }));
+                    }}
+                  >
+                    <span>
+                      <i18n.Translate>remove</i18n.Translate>
+                    </span>
+                  </button>
+                }
                 tooltip={i18n.str`Use to verify transaction in offline mode.`}
               />
               <InputSearchOnList
                 label={i18n.str`Search device`}
                 onChange={(p) => setState((v) => ({ ...v, otpId: p?.id }))}
-                list={deviceList.map(e => ({
+                list={deviceList.map((e) => ({
                   description: e.device_description,
-                  id: e.otp_device_id
+                  id: e.otp_device_id,
                 }))}
               />
-
             </FormProvider>
 
             <div class="buttons is-right mt-5">
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..593850268 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
@@ -19,16 +19,16 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useTemplateAPI } from "../../../../hooks/templates.js";
 import { Notification } from "../../../../utils/types.js";
 import { CreatePage } from "./CreatePage.js";
 
-export type Entity = MerchantBackend.Transfers.TransferInformation;
+export type Entity = TalerMerchantApi.TransferInformation;
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
@@ -44,7 +44,7 @@ export default function CreateTransfer({ onConfirm, onBack }: 
Props): VNode {
       <NotificationCard notification={notif} />
       <CreatePage
         onBack={onBack}
-        onCreate={(request: MerchantBackend.Template.TemplateAddDetails) => {
+        onCreate={(request: TalerMerchantApi.TemplateAddDetails) => {
           return createTemplate(request)
             .then(() => onConfirm())
             .catch((error) => {
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..84ff9e0f2 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
@@ -19,20 +19,19 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { h, VNode } from "preact";
-import { MerchantBackend } from "../../../../declaration.js";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { CardTable } from "./Table.js";
 
 export interface Props {
-  templates: MerchantBackend.Template.TemplateEntry[];
+  templates: TalerMerchantApi.TemplateEntry[];
   onLoadMoreBefore?: () => void;
   onLoadMoreAfter?: () => void;
   onCreate: () => void;
-  onDelete: (e: MerchantBackend.Template.TemplateEntry) => void;
-  onSelect: (e: MerchantBackend.Template.TemplateEntry) => void;
-  onNewOrder: (e: MerchantBackend.Template.TemplateEntry) => void;
-  onQR: (e: MerchantBackend.Template.TemplateEntry) => void;
+  onDelete: (e: TalerMerchantApi.TemplateEntry) => void;
+  onSelect: (e: TalerMerchantApi.TemplateEntry) => void;
+  onNewOrder: (e: TalerMerchantApi.TemplateEntry) => void;
+  onQR: (e: TalerMerchantApi.TemplateEntry) => void;
 }
 
 export function ListPage({
@@ -45,9 +44,7 @@ export function ListPage({
   onLoadMoreBefore,
   onLoadMoreAfter,
 }: Props): VNode {
-  const form = { payto_uri: "" };
 
-  const { i18n } = useTranslationContext();
   return (
       <CardTable
         templates={templates.map((o) => ({
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..11caca970 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
@@ -19,12 +19,12 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { StateUpdater, useState } from "preact/hooks";
-import { MerchantBackend } from "../../../../declaration.js";
 
-type Entity = MerchantBackend.Template.TemplateEntry;
+type Entity = TalerMerchantApi.TemplateEntry;
 
 interface Props {
   templates: Entity[];
@@ -117,11 +117,6 @@ interface TableProps {
   onLoadMoreAfter?: () => void;
 }
 
-function toggleSelected<T>(id: T): (prev: T[]) => T[] {
-  return (prev: T[]): T[] =>
-    prev.indexOf(id) == -1 ? [...prev, id] : prev.filter((e) => e != id);
-}
-
 function Table({
   instances,
   onLoadMoreAfter,
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..2138d24a4 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
@@ -19,29 +19,28 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
+import { JumpToElementById } from 
"../../../../components/form/JumpToElementById.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
+import { ConfirmModal } from "../../../../components/modal/index.js";
 import {
   useInstanceTemplates,
   useTemplateAPI,
 } from "../../../../hooks/templates.js";
 import { Notification } from "../../../../utils/types.js";
 import { ListPage } from "./ListPage.js";
-import { HttpStatusCode, TranslatedString } from "@gnu-taler/taler-util";
-import { ConfirmModal } from "../../../../components/modal/index.js";
-import { JumpToElementById } from 
"../../../../components/form/JumpToElementById.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onCreate: () => void;
   onSelect: (id: string) => void;
@@ -64,7 +63,7 @@ export default function ListTemplates({
   const { deleteTemplate, testTemplateExist } = useTemplateAPI();
   const result = useInstanceTemplates({ position }, (id) => setPosition(id));
   const [deleting, setDeleting] =
-    useState<MerchantBackend.Template.TemplateEntry | null>(null);
+    useState<TalerMerchantApi.TemplateEntry | null>(null);
 
   if (result.loading) return <Loading />;
   if (!result.ok) {
@@ -93,7 +92,7 @@ export default function ListTemplates({
       />
 
       <ListPage
-        templates={result.data.templates}
+        templates={result.data.templates_list}
         onLoadMoreBefore={
           result.isReachingStart ? result.loadMorePrev : undefined
         }
@@ -108,7 +107,7 @@ export default function ListTemplates({
         onQR={(e) => {
           onQR(e.template_id);
         }}
-        onDelete={(e: MerchantBackend.Template.TemplateEntry) => {
+        onDelete={(e: TalerMerchantApi.TemplateEntry) => {
           setDeleting(e)
         }
         }
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..d48e5e956 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
@@ -19,8 +19,11 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { stringifyPayTemplateUri } from "@gnu-taler/taler-util";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import { TalerMerchantApi, stringifyPayTemplateUri } from 
"@gnu-taler/taler-util";
+import {
+  useMerchantApiContext,
+  useTranslationContext,
+} from "@gnu-taler/web-util/browser";
 import { VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { QR } from "../../../../components/exception/QR.js";
@@ -30,24 +33,22 @@ import {
 } from "../../../../components/form/FormProvider.js";
 import { Input } from "../../../../components/form/Input.js";
 import { InputCurrency } from "../../../../components/form/InputCurrency.js";
-import { useBackendContext } from "../../../../context/backend.js";
-import { useConfigContext } from "../../../../context/config.js";
-import { useInstanceContext } from "../../../../context/instance.js";
-import { MerchantBackend } from "../../../../declaration.js";
+import { useSessionContext } from "../../../../context/session.js";
 
-type Entity = MerchantBackend.Template.UsingTemplateDetails;
+type Entity = TalerMerchantApi.UsingTemplateDetails;
 
 interface Props {
-  contract: MerchantBackend.Template.TemplateContractDetails;
+  contract: TalerMerchantApi.TemplateContractDetails;
   id: string;
   onBack?: () => void;
 }
 
 export function QrPage({ contract, id: templateId, onBack }: Props): VNode {
   const { i18n } = useTranslationContext();
-  const { url: backendURL } = useBackendContext()
-  const { id: instanceId } = useInstanceContext();
-  const config = useConfigContext();
+  const {
+    state: { backendUrl },
+  } = useSessionContext();
+  const { config } = useMerchantApiContext();
 
   const [state, setState] = useState<Partial<Entity>>({
     amount: contract.amount,
@@ -59,30 +60,26 @@ export function QrPage({ contract, id: templateId, onBack 
}: Props): VNode {
   const fixedAmount = !!contract.amount;
   const fixedSummary = !!contract.summary;
 
-  const templateParams: Record<string, string> = {}
+  const templateParams: Record<string, string> = {};
   if (!fixedAmount) {
     if (state.amount) {
-      templateParams.amount = state.amount
+      templateParams.amount = state.amount;
     } else {
-      templateParams.amount = config.currency
+      templateParams.amount = config.currency;
     }
   }
 
   if (!fixedSummary) {
-    templateParams.summary = state.summary ?? ""
+    templateParams.summary = state.summary ?? "";
   }
 
-  const merchantBaseUrl = new URL(backendURL).href;
+  const merchantBaseUrl = backendUrl;
 
   const payTemplateUri = stringifyPayTemplateUri({
     merchantBaseUrl,
     templateId,
-    templateParams
-  })
-
-  const issuer = encodeURIComponent(
-    `${new URL(backendURL).host}/${instanceId}`,
-  );
+    templateParams,
+  });
 
   return (
     <div>
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..37f0e5c74 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
@@ -19,30 +19,27 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
-  HttpError,
-  useTranslationContext,
+  HttpError
 } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import {
-  useTemplateAPI,
-  useTemplateDetails,
+  useTemplateDetails
 } from "../../../../hooks/templates.js";
 import { Notification } from "../../../../utils/types.js";
 import { QrPage } from "./QrPage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
 
-export type Entity = MerchantBackend.Transfers.TransferInformation;
+export type Entity = TalerMerchantApi.TransferInformation;
 interface Props {
   onBack?: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
   tid: string;
 }
 
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..f4092b61b 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
@@ -23,10 +23,11 @@ import {
   AmountString,
   Amounts,
   Duration,
+  TalerMerchantApi,
   assertUnreachable
 } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { Fragment, VNode, h } from "preact";
+import { VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { AsyncButton } from "../../../../components/exception/AsyncButton.js";
 import {
@@ -37,11 +38,9 @@ import { Input } from "../../../../components/form/Input.js";
 import { InputCurrency } from "../../../../components/form/InputCurrency.js";
 import { InputDuration } from "../../../../components/form/InputDuration.js";
 import { InputNumber } from "../../../../components/form/InputNumber.js";
-import { InputTab } from "../../../../components/form/InputTab.js";
-import { InputWithAddon } from "../../../../components/form/InputWithAddon.js";
-import { useBackendContext } from "../../../../context/backend.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { InputSearchOnList } from 
"../../../../components/form/InputSearchOnList.js";
+import { InputTab } from "../../../../components/form/InputTab.js";
+import { useSessionContext } from "../../../../context/session.js";
 import { useInstanceOtpDevices } from "../../../../hooks/otp.js";
 
 enum Steps {
@@ -61,14 +60,17 @@ type Entity = {
 };
 
 interface Props {
-  onUpdate: (d: MerchantBackend.Template.TemplatePatchDetails) => 
Promise<void>;
+  onUpdate: (d: TalerMerchantApi.TemplatePatchDetails) => Promise<void>;
   onBack?: () => void;
-  template: MerchantBackend.Template.TemplateDetails;
+  template: TalerMerchantApi.TemplateDetails;
 }
 
 export function UpdatePage({ template, onUpdate, onBack }: Props): VNode {
   const { i18n } = useTranslationContext();
-  const { url: backendURL } = useBackendContext()
+  const {
+    state: { backendUrl },
+  } = useSessionContext();
+
 
   const intialStep =
     template.template_contract.amount === undefined && 
template.template_contract.summary === undefined
@@ -187,7 +189,7 @@ export function UpdatePage({ template, onUpdate, onBack }: 
Props): VNode {
               <div class="level-left">
                 <div class="level-item">
                   <span class="is-size-4">
-                    {backendURL}/templates/{template.otp_id}
+                    {new URL(`templates/${template.otp_id}`,backendUrl).href}
                   </span>
                 </div>
               </div>
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..ba1939914 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
@@ -19,32 +19,31 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend, WithId } from "../../../../declaration.js";
 import {
   useTemplateAPI,
   useTemplateDetails,
 } from "../../../../hooks/templates.js";
 import { Notification } from "../../../../utils/types.js";
 import { UpdatePage } from "./UpdatePage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
 
-export type Entity = MerchantBackend.Template.TemplatePatchDetails & WithId;
+export type Entity = TalerMerchantApi.TemplatePatchDetails & WithId;
 
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
   tid: string;
 }
 export default function UpdateTemplate({
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..58e63cc8e 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
@@ -19,6 +19,7 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { useState } from "preact/hooks";
@@ -29,13 +30,12 @@ import {
 } from "../../../../components/form/FormProvider.js";
 import { Input } from "../../../../components/form/Input.js";
 import { InputCurrency } from "../../../../components/form/InputCurrency.js";
-import { MerchantBackend } from "../../../../declaration.js";
 
-type Entity = MerchantBackend.Template.UsingTemplateDetails;
+type Entity = TalerMerchantApi.UsingTemplateDetails;
 
 interface Props {
   id: string;
-  template: MerchantBackend.Template.TemplateDetails;
+  template: TalerMerchantApi.TemplateDetails;
   onCreateOrder: (d: Entity) => Promise<void>;
   onBack?: () => void;
 }
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..64c38c86b 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
@@ -19,31 +19,30 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import {
   useTemplateAPI,
   useTemplateDetails,
 } from "../../../../hooks/templates.js";
 import { Notification } from "../../../../utils/types.js";
 import { UsePage } from "./UsePage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
 
-export type Entity = MerchantBackend.Transfers.TransferInformation;
+export type Entity = TalerMerchantApi.TransferInformation;
 interface Props {
   onBack?: () => void;
   onOrderCreated: (id: string) => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
   tid: string;
 }
 
@@ -83,7 +82,7 @@ export default function TemplateUsePage({
         id={tid}
         onBack={onBack}
         onCreateOrder={(
-          request: MerchantBackend.Template.UsingTemplateDetails,
+          request: TalerMerchantApi.UsingTemplateDetails,
         ) => {
           return createOrderFromTemplate(tid, request)
             .then((res) => onOrderCreated(res.data.order_id))
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..f2b1db29b 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
@@ -25,19 +25,23 @@ import { useState } from "preact/hooks";
 import { AsyncButton } from "../../../components/exception/AsyncButton.js";
 import { FormProvider } from "../../../components/form/FormProvider.js";
 import { Input } from "../../../components/form/Input.js";
-import { useInstanceContext } from "../../../context/instance.js";
-import { AccessToken } from "../../../declaration.js";
 import { NotificationCard } from "../../../components/menu/index.js";
+import { useSessionContext } from "../../../context/session.js";
+import { AccessToken } from "@gnu-taler/taler-util";
 
 interface Props {
-  instanceId: string;
   hasToken: boolean | undefined;
   onClearToken: (c: AccessToken | undefined) => void;
   onNewToken: (c: AccessToken | undefined, s: AccessToken) => void;
   onBack?: () => void;
 }
 
-export function DetailPage({ instanceId, hasToken, onBack, onNewToken, 
onClearToken }: Props): VNode {
+export function DetailPage({
+  hasToken,
+  onBack,
+  onNewToken,
+  onClearToken,
+}: Props): VNode {
   type State = { old_token: string; new_token: string; repeat_token: string };
   const [form, setValue] = useState<Partial<State>>({
     old_token: "",
@@ -47,9 +51,10 @@ export function DetailPage({ instanceId, hasToken, onBack, 
onNewToken, onClearTo
   const { i18n } = useTranslationContext();
 
   const errors = {
-    old_token: hasToken && !form.old_token
-      ? i18n.str`you need your access token to perform the operation`
-      : undefined,
+    old_token:
+      hasToken && !form.old_token
+        ? i18n.str`you need your access token to perform the operation`
+        : undefined,
     new_token: !form.new_token
       ? i18n.str`cannot be empty`
       : form.new_token === form.old_token
@@ -65,15 +70,17 @@ export function DetailPage({ instanceId, hasToken, onBack, 
onNewToken, onClearTo
     (k) => (errors as any)[k] !== undefined,
   );
 
-  const instance = useInstanceContext();
+  const { state } = useSessionContext();
 
-  const text = i18n.str`You are updating the access token from instance with 
id "${instance.id}"`;
+  const text = i18n.str`You are updating the access token from instance with 
id "${state.instance}"`;
 
   async function submitForm() {
     if (hasErrors) return;
-    const oldToken = hasToken ? `secret-token:${form.old_token}` as 
AccessToken : undefined;
+    const oldToken = hasToken
+      ? (`secret-token:${form.old_token}` as AccessToken)
+      : undefined;
     const newToken = `secret-token:${form.new_token}` as AccessToken;
-    onNewToken(oldToken, newToken)
+    onNewToken(oldToken, newToken);
   }
 
   return (
@@ -84,9 +91,7 @@ export function DetailPage({ instanceId, hasToken, onBack, 
onNewToken, onClearTo
             <div class="level">
               <div class="level-left">
                 <div class="level-item">
-                  <span class="is-size-4">
-                    {text}
-                  </span>
+                  <span class="is-size-4">{text}</span>
                 </div>
               </div>
             </div>
@@ -94,7 +99,7 @@ export function DetailPage({ instanceId, hasToken, onBack, 
onNewToken, onClearTo
         </section>
         <hr />
 
-        {!hasToken &&
+        {!hasToken && (
           <NotificationCard
             notification={{
               message: i18n.str`This instance doesn't have authentication 
token.`,
@@ -102,7 +107,7 @@ export function DetailPage({ instanceId, hasToken, onBack, 
onNewToken, onClearTo
               type: "WARN",
             }}
           />
-        }
+        )}
 
         <div class="columns">
           <div class="column" />
@@ -119,7 +124,8 @@ export function DetailPage({ instanceId, hasToken, onBack, 
onNewToken, onClearTo
                     />
                     <p>
                       <i18n.Translate>
-                        Clearing the access token will mean public access to 
the instance.
+                        Clearing the access token will mean public access to 
the
+                        instance.
                       </i18n.Translate>
                     </p>
                     <div class="buttons is-right mt-5">
@@ -127,10 +133,11 @@ export function DetailPage({ instanceId, hasToken, 
onBack, onNewToken, onClearTo
                         class="button"
                         onClick={() => {
                           if (hasToken) {
-                            const oldToken = `secret-token:${form.old_token}` 
as AccessToken;
-                            onClearToken(oldToken)
+                            const oldToken =
+                              `secret-token:${form.old_token}` as AccessToken;
+                            onClearToken(oldToken);
                           } else {
-                            onClearToken(undefined)
+                            onClearToken(undefined);
                           }
                         }}
                       >
@@ -140,7 +147,6 @@ export function DetailPage({ instanceId, hasToken, onBack, 
onNewToken, onClearTo
                   </Fragment>
                 )}
 
-
                 <Input<State>
                   name="new_token"
                   label={i18n.str`New access token`}
@@ -176,7 +182,6 @@ export function DetailPage({ instanceId, hasToken, onBack, 
onNewToken, onClearTo
           </div>
           <div class="column" />
         </div>
-
       </section>
     </div>
   );
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..13b5c45f1 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
@@ -13,22 +13,20 @@
  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 { HttpStatusCode } from "@gnu-taler/taler-util";
-import { ErrorType, HttpError, useTranslationContext } from 
"@gnu-taler/web-util/browser";
+import { AccessToken, HttpStatusCode, TalerErrorDetail } from 
"@gnu-taler/taler-util";
+import { ErrorType, HttpError, useMerchantApiContext, useTranslationContext } 
from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
-import { Loading } from "../../../components/exception/loading.js";
-import { AccessToken, MerchantBackend } from "../../../declaration.js";
-import { useInstanceAPI, useInstanceDetails } from 
"../../../hooks/instance.js";
-import { DetailPage } from "./DetailPage.js";
-import { useInstanceContext } from "../../../context/instance.js";
 import { useState } from "preact/hooks";
+import { Loading } from "../../../components/exception/loading.js";
 import { NotificationCard } from "../../../components/menu/index.js";
+import { useInstanceAPI, useInstanceDetails } from 
"../../../hooks/instance.js";
 import { Notification } from "../../../utils/types.js";
-import { useBackendContext } from "../../../context/backend.js";
+import { DetailPage } from "./DetailPage.js";
+import { useSessionContext } from "../../../context/session.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
   onChange: () => void;
   onNotFound: () => VNode;
   onCancel: () => void;
@@ -42,10 +40,10 @@ export default function Token({
   onCancel,
 }: Props): VNode {
   const { i18n } = useTranslationContext();
-
+  const { lib } = useMerchantApiContext();
+  const { logIn } = useSessionContext();
   const [notif, setNotif] = useState<Notification | undefined>(undefined);
-  const { clearAccessToken, setNewAccessToken } = useInstanceAPI();
-  const { id } = useInstanceContext();
+  const { clearAccessToken } = useInstanceAPI();
   const result = useInstanceDetails()
 
   if (result.loading) return <Loading />;
@@ -63,13 +61,12 @@ export default function Token({
     return onLoadError(result);
   }
 
-  const hasToken = result.data.auth.method === "token"
+  const hasToken = result.data.auth.type === "token"
 
   return (
     <Fragment>
       <NotificationCard notification={notif} />
       <DetailPage
-        instanceId={id}
         onBack={onCancel}
         hasToken={hasToken}
         onClearToken={async (currentToken): Promise<void> => {
@@ -88,8 +85,26 @@ export default function Token({
         }}
         onNewToken={async (currentToken, newToken): Promise<void> => {
           try {
-            await setNewAccessToken(currentToken, newToken);
-            onChange();
+            await 
lib.management.updateCurrentInstanceAuthentication(currentToken, {
+              token: newToken,
+              method: "token"
+            })
+            const resp = await 
lib.authenticate.createAccessTokenBearer(newToken, {
+              scope: "write",
+              duration: {
+                d_us: "forever"
+              },
+              refreshable: true,
+            })
+            if (resp.type === "ok") {
+              logIn({ token: resp.body.token })
+              onChange();
+            } else {
+              setNotif({
+                message: i18n.str`Failed to set new token`,
+                type: "ERROR",
+              });
+            }
           } catch (error) {
             if (error instanceof Error) {
               setNotif({
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..91aabe58e 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
@@ -19,8 +19,9 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { AmountString, TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { h, VNode } from "preact";
+import { VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { AsyncButton } from "../../../../components/exception/AsyncButton.js";
 import {
@@ -30,14 +31,12 @@ import {
 import { Input } from "../../../../components/form/Input.js";
 import { InputCurrency } from "../../../../components/form/InputCurrency.js";
 import { InputSelector } from "../../../../components/form/InputSelector.js";
-import { useConfigContext } from "../../../../context/config.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import {
   CROCKFORD_BASE32_REGEX,
   URL_REGEX,
 } from "../../../../utils/constants.js";
 
-type Entity = MerchantBackend.Transfers.TransferInformation;
+type Entity = TalerMerchantApi.TransferInformation;
 
 interface Props {
   onCreate: (d: Entity) => Promise<void>;
@@ -47,13 +46,12 @@ interface Props {
 
 export function CreatePage({ accounts, onCreate, onBack }: Props): VNode {
   const { i18n } = useTranslationContext();
-  const { currency } = useConfigContext();
 
   const [state, setState] = useState<Partial<Entity>>({
     wtid: "",
     // payto_uri: ,
     // exchange_url: 'http://exchange.taler:8081/',
-    credit_amount: ``,
+    credit_amount: `` as AmountString,
   });
 
   const errors: FormErrors<Entity> = {
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..e640e47f6 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
@@ -19,18 +19,17 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
-import { useInstanceDetails } from "../../../../hooks/instance.js";
+import { useInstanceBankAccounts } from "../../../../hooks/bank.js";
 import { useTransferAPI } from "../../../../hooks/transfer.js";
 import { Notification } from "../../../../utils/types.js";
 import { CreatePage } from "./CreatePage.js";
-import { useBankAccountDetails, useInstanceBankAccounts } from 
"../../../../hooks/bank.js";
 
-export type Entity = MerchantBackend.Transfers.TransferInformation;
+export type Entity = TalerMerchantApi.TransferInformation;
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
@@ -51,7 +50,7 @@ export default function CreateTransfer({ onConfirm, onBack }: 
Props): VNode {
       <CreatePage
         onBack={onBack}
         accounts={accounts}
-        onCreate={(request: MerchantBackend.Transfers.TransferInformation) => {
+        onCreate={(request: TalerMerchantApi.TransferInformation) => {
           return informTransfer(request)
             .then(() => onConfirm())
             .catch((error) => {
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..def03fe27 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
@@ -19,7 +19,8 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { h, VNode, FunctionalComponent } from "preact";
+import { AmountString, PaytoString } from "@gnu-taler/taler-util";
+import { FunctionalComponent, h } from "preact";
 import { ListPage as TestedComponent } from "./ListPage.js";
 
 export default {
@@ -50,8 +51,8 @@ export const Example = createExample(TestedComponent, {
   transfers: [
     {
       exchange_url: "http://exchange.url/";,
-      credit_amount: "TESTKUDOS:10",
-      payto_uri: "payto//x-taler-bank/bank:8080/account",
+      credit_amount: "TESTKUDOS:10" as AmountString,
+      payto_uri: "payto//x-taler-bank/bank:8080/account" as PaytoString,
       transfer_serial_id: 123123123,
       wtid: "!@KJELQKWEJ!L@K#!J@",
       confirmed: true,
@@ -62,8 +63,8 @@ export const Example = createExample(TestedComponent, {
     },
     {
       exchange_url: "http://exchange.url/";,
-      credit_amount: "TESTKUDOS:10",
-      payto_uri: "payto//x-taler-bank/bank:8080/account",
+      credit_amount: "TESTKUDOS:10" as AmountString,
+      payto_uri: "payto//x-taler-bank/bank:8080/account" as PaytoString,
       transfer_serial_id: 123123123,
       wtid: "!@KJELQKWEJ!L@K#!J@",
       confirmed: true,
@@ -74,8 +75,8 @@ export const Example = createExample(TestedComponent, {
     },
     {
       exchange_url: "http://exchange.url/";,
-      credit_amount: "TESTKUDOS:10",
-      payto_uri: "payto//x-taler-bank/bank:8080/account",
+      credit_amount: "TESTKUDOS:10" as AmountString,
+      payto_uri: "payto//x-taler-bank/bank:8080/account" as PaytoString,
       transfer_serial_id: 123123123,
       wtid: "!@KJELQKWEJ!L@K#!J@",
       confirmed: true,
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..7b54dc5ed 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
@@ -23,11 +23,11 @@ import { useTranslationContext } from 
"@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { FormProvider } from "../../../../components/form/FormProvider.js";
 import { InputSelector } from "../../../../components/form/InputSelector.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { CardTable } from "./Table.js";
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 
 export interface Props {
-  transfers: MerchantBackend.Transfers.TransferDetails[];
+  transfers: TalerMerchantApi.TransferDetails[];
   onLoadMoreBefore?: () => void;
   onLoadMoreAfter?: () => void;
   onShowAll: () => void;
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..cf7ebe922 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
@@ -19,14 +19,14 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 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;
+type Entity = TalerMerchantApi.TransferDetails & WithId;
 
 interface Props {
   transfers: Entity[];
@@ -108,11 +108,6 @@ interface TableProps {
   onLoadMoreAfter?: () => void;
 }
 
-function toggleSelected<T>(id: T): (prev: T[]) => T[] {
-  return (prev: T[]): T[] =>
-    prev.indexOf(id) == -1 ? [...prev, id] : prev.filter((e) => e != id);
-}
-
 function Table({
   instances,
   onLoadMoreAfter,
@@ -122,7 +117,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..15706b4c5 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
@@ -19,20 +19,18 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpStatusCode, TalerErrorDetail } from "@gnu-taler/taler-util";
 import { ErrorType, HttpError } from "@gnu-taler/web-util/browser";
-import { h, VNode } from "preact";
+import { VNode, h } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
-import { MerchantBackend } from "../../../../declaration.js";
-import { useInstanceDetails } from "../../../../hooks/instance.js";
+import { useInstanceBankAccounts } from "../../../../hooks/bank.js";
 import { useInstanceTransfers } from "../../../../hooks/transfer.js";
 import { ListPage } from "./ListPage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
-import { useInstanceBankAccounts } from "../../../../hooks/bank.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onCreate: () => void;
 }
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..5514b68d9 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
@@ -19,7 +19,7 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { h, VNode, FunctionalComponent } from "preact";
+import { FunctionalComponent, h } from "preact";
 import { UpdatePage as TestedComponent } from "./UpdatePage.js";
 
 export default {
@@ -43,7 +43,7 @@ function createExample<Props>(
 export const Example = createExample(TestedComponent, {
   selected: {
     name: "name",
-    auth: { method: "external" },
+    auth: { type: "external" },
     address: {},
     user_type: "business",
     use_stefan: true,
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..cde58967f 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
@@ -19,8 +19,9 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { Duration, TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { h, VNode } from "preact";
+import { VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { AsyncButton } from "../../../components/exception/AsyncButton.js";
 import {
@@ -28,26 +29,24 @@ import {
   FormProvider,
 } from "../../../components/form/FormProvider.js";
 import { DefaultInstanceFormFields } from 
"../../../components/instance/DefaultInstanceFormFields.js";
-import { useInstanceContext } from "../../../context/instance.js";
-import { MerchantBackend } from "../../../declaration.js";
+import { useSessionContext } from "../../../context/session.js";
 import { undefinedIfEmpty } from "../../../utils/table.js";
-import { Duration } from "@gnu-taler/taler-util";
 
-export type Entity = 
Omit<Omit<MerchantBackend.Instances.InstanceReconfigurationMessage, 
"default_pay_delay">, "default_wire_transfer_delay"> & {
+export type Entity = 
Omit<Omit<TalerMerchantApi.InstanceReconfigurationMessage, 
"default_pay_delay">, "default_wire_transfer_delay"> & {
   default_pay_delay: Duration,
   default_wire_transfer_delay: Duration,
 };
 
-//MerchantBackend.Instances.InstanceAuthConfigurationMessage
+//TalerMerchantApi.InstanceAuthConfigurationMessage
 interface Props {
-  onUpdate: (d: MerchantBackend.Instances.InstanceReconfigurationMessage) => 
void;
-  selected: MerchantBackend.Instances.QueryInstancesResponse;
+  onUpdate: (d: TalerMerchantApi.InstanceReconfigurationMessage) => void;
+  selected: TalerMerchantApi.QueryInstancesResponse;
   isLoading: boolean;
   onBack: () => void;
 }
 
 function convert(
-  from: MerchantBackend.Instances.QueryInstancesResponse,
+  from: TalerMerchantApi.QueryInstancesResponse,
 ): Entity {
   const { default_pay_delay, default_wire_transfer_delay, ...rest } = from;
 
@@ -64,7 +63,7 @@ export function UpdatePage({
   selected,
   onBack,
 }: Props): VNode {
-  const { id } = useInstanceContext();
+  const { state } = useSessionContext();
 
   const [value, valueHandler] = useState<Partial<Entity>>(convert(selected));
 
@@ -107,7 +106,7 @@ export function UpdatePage({
 
   const submit = async (): Promise<void> => {
     const { default_pay_delay, default_wire_transfer_delay, ...rest } = value 
as Required<Entity>;
-    const result: MerchantBackend.Instances.InstanceReconfigurationMessage = {
+    const result: TalerMerchantApi.InstanceReconfigurationMessage = {
       default_pay_delay: Duration.toTalerProtocolDuration(default_pay_delay),
       default_wire_transfer_delay: 
Duration.toTalerProtocolDuration(default_wire_transfer_delay),
       ...rest,
@@ -125,7 +124,7 @@ export function UpdatePage({
               <div class="level-left">
                 <div class="level-item">
                   <span class="is-size-4">
-                    <i18n.Translate>Instance id</i18n.Translate>: <b>{id}</b>
+                    <i18n.Translate>Instance id</i18n.Translate>: 
<b>{state.instance}</b>
                   </span>
                 </div>
               </div>
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..d28ca0555 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
@@ -13,7 +13,7 @@
  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 { HttpStatusCode } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 import {
   ErrorType,
   HttpError,
@@ -24,8 +24,6 @@ import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../components/exception/loading.js";
 import { NotificationCard } from "../../../components/menu/index.js";
-import { useInstanceContext } from "../../../context/instance.js";
-import { AccessToken, MerchantBackend } from "../../../declaration.js";
 import {
   useInstanceAPI,
   useInstanceDetails,
@@ -41,8 +39,8 @@ export interface Props {
 
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
-  onUpdateError: (e: HttpError<MerchantBackend.ErrorDetail>) => void;
+  onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
+  onUpdateError: (e: HttpError<TalerErrorDetail>) => void;
 }
 
 export default function Update(props: Props): VNode {
@@ -65,12 +63,11 @@ function CommonUpdate(
     onConfirm,
     onLoadError,
     onNotFound,
-    onUpdateError,
     onUnauthorized,
   }: Props,
   result: HttpResponse<
-    MerchantBackend.Instances.QueryInstancesResponse,
-    MerchantBackend.ErrorDetail
+    TalerMerchantApi.QueryInstancesResponse,
+    TalerErrorDetail
   >,
   updateInstance: any,
 ): VNode {
@@ -100,7 +97,7 @@ function CommonUpdate(
         isLoading={false}
         selected={result.data}
         onUpdate={(
-          d: MerchantBackend.Instances.InstanceReconfigurationMessage,
+          d: TalerMerchantApi.InstanceReconfigurationMessage,
         ): Promise<void> => {
           return updateInstance(d)
             .then(onConfirm)
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..8792aabea 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
@@ -28,14 +28,10 @@ import {
   FormProvider,
 } from "../../../../components/form/FormProvider.js";
 import { Input } from "../../../../components/form/Input.js";
-import { InputCurrency } from "../../../../components/form/InputCurrency.js";
-import { InputDuration } from "../../../../components/form/InputDuration.js";
-import { InputNumber } from "../../../../components/form/InputNumber.js";
-import { useBackendContext } from "../../../../context/backend.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { InputSelector } from "../../../../components/form/InputSelector.js";
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 
-type Entity = MerchantBackend.Webhooks.WebhookAddDetails;
+type Entity = TalerMerchantApi.WebhookAddDetails;
 
 interface Props {
   onCreate: (d: Entity) => Promise<void>;
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..42a432cf0 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
@@ -23,12 +23,12 @@ import { useTranslationContext } from 
"@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useWebhookAPI } from "../../../../hooks/webhooks.js";
 import { Notification } from "../../../../utils/types.js";
 import { CreatePage } from "./CreatePage.js";
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 
-export type Entity = MerchantBackend.Webhooks.WebhookAddDetails;
+export type Entity = TalerMerchantApi.WebhookAddDetails;
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
@@ -44,7 +44,7 @@ export default function CreateWebhook({ onConfirm, onBack }: 
Props): VNode {
       <NotificationCard notification={notif} />
       <CreatePage
         onBack={onBack}
-        onCreate={(request: MerchantBackend.Webhooks.WebhookAddDetails) => {
+        onCreate={(request: TalerMerchantApi.WebhookAddDetails) => {
           return createWebhook(request)
             .then(() => onConfirm())
             .catch((error) => {
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..98bd61d8f 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
@@ -20,17 +20,17 @@
  */
 
 import { h, VNode } from "preact";
-import { MerchantBackend } from "../../../../declaration.js";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { CardTable } from "./Table.js";
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 
 export interface Props {
-  webhooks: MerchantBackend.Webhooks.WebhookEntry[];
+  webhooks: TalerMerchantApi.WebhookEntry[];
   onLoadMoreBefore?: () => void;
   onLoadMoreAfter?: () => void;
   onCreate: () => void;
-  onDelete: (e: MerchantBackend.Webhooks.WebhookEntry) => void;
-  onSelect: (e: MerchantBackend.Webhooks.WebhookEntry) => void;
+  onDelete: (e: TalerMerchantApi.WebhookEntry) => void;
+  onSelect: (e: TalerMerchantApi.WebhookEntry) => void;
 }
 
 export function ListPage({
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..2cafc7f9a 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
@@ -19,12 +19,12 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h, VNode } from "preact";
 import { StateUpdater, useState } from "preact/hooks";
-import { MerchantBackend } from "../../../../declaration.js";
 
-type Entity = MerchantBackend.Webhooks.WebhookEntry;
+type Entity = TalerMerchantApi.WebhookEntry;
 
 interface Props {
   webhooks: Entity[];
@@ -109,11 +109,6 @@ interface TableProps {
   onLoadMoreAfter?: () => void;
 }
 
-function toggleSelected<T>(id: T): (prev: T[]) => T[] {
-  return (prev: T[]): T[] =>
-    prev.indexOf(id) == -1 ? [...prev, id] : prev.filter((e) => e != id);
-}
-
 function Table({
   instances,
   onLoadMoreAfter,
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..17e767337 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
@@ -28,18 +28,17 @@ import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend } from "../../../../declaration.js";
 import {
   useInstanceWebhooks,
   useWebhookAPI,
 } from "../../../../hooks/webhooks.js";
 import { Notification } from "../../../../utils/types.js";
 import { ListPage } from "./ListPage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onCreate: () => void;
   onSelect: (id: string) => void;
@@ -87,7 +86,7 @@ export default function ListWebhooks({
         onSelect={(e) => {
           onSelect(e.webhook_id);
         }}
-        onDelete={(e: MerchantBackend.Webhooks.WebhookEntry) =>
+        onDelete={(e: TalerMerchantApi.WebhookEntry) =>
           deleteWebhook(e.webhook_id)
             .then(() =>
               setNotif({
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..6aca62582 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
@@ -28,10 +28,9 @@ import {
   FormProvider,
 } from "../../../../components/form/FormProvider.js";
 import { Input } from "../../../../components/form/Input.js";
-import { useBackendContext } from "../../../../context/backend.js";
-import { MerchantBackend, WithId } from "../../../../declaration.js";
+import { TalerMerchantApi } from "@gnu-taler/taler-util";
 
-type Entity = MerchantBackend.Webhooks.WebhookPatchDetails & WithId;
+type Entity = TalerMerchantApi.WebhookPatchDetails & WithId;
 
 interface Props {
   onUpdate: (d: Entity) => Promise<void>;
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..97b4f44ba 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
@@ -28,23 +28,22 @@ import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { NotificationCard } from "../../../../components/menu/index.js";
-import { MerchantBackend, WithId } from "../../../../declaration.js";
 import {
   useWebhookAPI,
   useWebhookDetails,
 } from "../../../../hooks/webhooks.js";
 import { Notification } from "../../../../utils/types.js";
 import { UpdatePage } from "./UpdatePage.js";
-import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from 
"@gnu-taler/taler-util";
 
-export type Entity = MerchantBackend.Webhooks.WebhookPatchDetails & WithId;
+export type Entity = TalerMerchantApi.WebhookPatchDetails & WithId;
 
 interface Props {
   onBack?: () => void;
   onConfirm: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
   tid: string;
 }
 export default function UpdateWebhook({
diff --git a/packages/merchant-backoffice-ui/src/paths/login/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/login/index.tsx
index 6c33dd06e..6a698186a 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,252 @@
  * @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 {
+  HttpStatusCode
+} from "@gnu-taler/taler-util";
+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 {
+  useSessionContext
+} from "../../context/session.js";
 import { Notification } from "../../utils/types.js";
 
-interface Props {
-  onConfirm: (token: LoginToken | undefined) => void;
-}
+interface Props { }
 
-function normalizeToken(r: string): AccessToken {
-  return `secret-token:${r}` as AccessToken;
-}
+const tokenRequest = {
+  scope: "write",
+  duration: {
+    d_us: "forever" as const,
+  },
+  refreshable: true,
+};
 
-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 { state, logIn } = useSessionContext();
+  const { lib } = useMerchantApiContext();
 
   const { i18n } = useTranslationContext();
 
-
-  const doLogin = useCallback(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 });
+  async function doImpersonateImpl(instanceId: string) {
+    const result = await lib
+      .impersonate(instanceId)
+      .createAccessTokenBearer(token, tokenRequest);
+    if (result.type === "ok") {
+      const { token } = result.body;
+      logIn({ 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 }}
-          >
+  }
+  async function doLoginImpl() {
+    const result = await lib.authenticate.createAccessTokenBearer(
+      token,
+      tokenRequest,
+    );
+    if (result.type === "ok") {
+      const { token } = result.body;
+      logIn({ token });
+      return;
+    } else {
+      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;
+        }
+      }
+    }
+  }
 
-            <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>
+  if (state.status === "loggedIn" && state.impersonate !== undefined) {
+    //the user is loggedin but trying to do an impersonation
+    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
+                            ? doImpersonateImpl(state.instance)
+                            : 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={() => doImpersonateImpl(state.instance)}>
+                <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..6290f48e6 100644
--- a/packages/merchant-backoffice-ui/src/paths/settings/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/settings/index.tsx
@@ -1,10 +1,30 @@
+/*
+ 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 { useLang, useTranslationContext } from "@gnu-taler/web-util/browser";
 import { VNode, h } from "preact";
-import { FormErrors, FormProvider } from 
"../../components/form/FormProvider.js";
+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 { Preferences, usePreference } from "../../hooks/preference.js";
+import { AbsoluteTime } from "@gnu-taler/taler-util";
 
 function getBrowserLang(): string | undefined {
   if (typeof window === "undefined") return undefined;
@@ -14,99 +34,107 @@ function getBrowserLang(): string | undefined {
 }
 
 export function Settings({ onClose }: { onClose?: () => void }): VNode {
-  const { i18n } = useTranslationContext()
-  const borwserLang = getBrowserLang()
-  const { update } = useLang(undefined, {})
+  const { i18n } = useTranslationContext();
+  const borwserLang = getBrowserLang();
+  const { update } = useLang(undefined, {});
 
-  const [value, updateValue] = useSettings()
-  const errors: FormErrors<Settings> = {
-  }
+  const [value, , updateValue] = usePreference();
+  const errors: FormErrors<Preferences> = {};
 
-  function valueHandler(s: (d: Partial<Settings>) => Partial<Settings>): void {
-    const next = s(value)
-    const v: Settings = {
+  function valueHandler(s: (d: Partial<Preferences>) => Partial<Preferences>): 
void {
+    const next = s(value);
+    const v: Preferences = {
       advanceOrderMode: next.advanceOrderMode ?? false,
-      dateFormat: next.dateFormat ?? "ymd"
-    }
-    updateValue(v)
+      hideKycUntil: next.hideKycUntil ?? AbsoluteTime.never(),
+      dateFormat: next.dateFormat ?? "ymd",
+    };
+    updateValue(v);
   }
 
-  return <div>
-    <section class="section is-main-section">
-      <div class="columns">
-        <div class="column" />
-        <div class="column is-four-fifths">
-          <div>
-
-            <FormProvider<Settings>
-              name="settings"
-              errors={errors}
-              object={value}
-              valueHandler={valueHandler}
-            >
-              <div class="field is-horizontal">
-                <div class="field-label is-normal">
-                  <label class="label">
-                    <i18n.Translate>Language</i18n.Translate>
-                    <span class="icon has-tooltip-right" data-tooltip={"Force 
language setting instance of taking the browser"}>
-                      <i class="mdi mdi-information" />
-                    </span>
-                  </label>
-                </div>
-                <div class="field field-body has-addons is-flex-grow-3">
-                  <LangSelector />
-                  &nbsp;
-                  {borwserLang !== undefined && <button
-                    data-tooltip={i18n.str`generate random secret key`}
-                    class="button is-info mr-2"
-                    onClick={(e) => {
-                      update(borwserLang.substring(0, 2))
-                    }}
-                  >
-                    <i18n.Translate>Set default</i18n.Translate>
-                  </button>}
+  return (
+    <div>
+      <section class="section is-main-section">
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-four-fifths">
+            <div>
+              <FormProvider<Preferences>
+                name="settings"
+                errors={errors}
+                object={value}
+                valueHandler={valueHandler}
+              >
+                <div class="field is-horizontal">
+                  <div class="field-label is-normal">
+                    <label class="label">
+                      <i18n.Translate>Language</i18n.Translate>
+                      <span
+                        class="icon has-tooltip-right"
+                        data-tooltip={
+                          "Force language setting instance of taking the 
browser"
+                        }
+                      >
+                        <i class="mdi mdi-information" />
+                      </span>
+                    </label>
+                  </div>
+                  <div class="field field-body has-addons is-flex-grow-3">
+                    <LangSelector />
+                    &nbsp;
+                    {borwserLang !== undefined && (
+                      <button
+                        data-tooltip={i18n.str`generate random secret key`}
+                        class="button is-info mr-2"
+                        onClick={(e) => {
+                          update(borwserLang.substring(0, 2));
+                          e.preventDefault()
+                        }}
+                      >
+                        <i18n.Translate>Set default</i18n.Translate>
+                      </button>
+                    )}
+                  </div>
                 </div>
-              </div>
-              <InputToggle<Settings>
-                label={i18n.str`Advance order creation`}
-                tooltip={i18n.str`Shows more options in the order creation 
form`}
-                name="advanceOrderMode"
-              />
-              <InputSelector<Settings>
-                name="dateFormat"
-                label={i18n.str`Date format`}
-                expand={true}
-                help={
-                  value.dateFormat === "dmy" ? "31/12/2001" : value.dateFormat 
=== "mdy" ? "12/31/2001" : value.dateFormat === "ymd" ? "2001/12/31" : ""
-                }
-                toStr={(e) => {
-                  if (e === "ymd") return "year month day"
-                  if (e === "mdy") return "month day year"
-                  if (e === "dmy") return "day month year"
-                  return "choose one"
-                }}
-                values={[
-                  "ymd",
-                  "mdy",
-                  "dmy",
-                ]}
-                tooltip={i18n.str`how the date is going to be displayed`}
-              />
-            </FormProvider>
+                <InputToggle<Preferences>
+                  label={i18n.str`Advance order creation`}
+                  tooltip={i18n.str`Shows more options in the order creation 
form`}
+                  name="advanceOrderMode"
+                />
+                <InputSelector<Preferences>
+                  name="dateFormat"
+                  label={i18n.str`Date format`}
+                  expand={true}
+                  help={
+                    value.dateFormat === "dmy"
+                      ? "31/12/2001"
+                      : value.dateFormat === "mdy"
+                        ? "12/31/2001"
+                        : value.dateFormat === "ymd"
+                          ? "2001/12/31"
+                          : ""
+                  }
+                  toStr={(e) => {
+                    if (e === "ymd") return "year month day";
+                    if (e === "mdy") return "month day year";
+                    if (e === "dmy") return "day month year";
+                    return "choose one";
+                  }}
+                  values={["ymd", "mdy", "dmy"]}
+                  tooltip={i18n.str`how the date is going to be displayed`}
+                />
+              </FormProvider>
+            </div>
           </div>
+          <div class="column" />
         </div>
-        <div class="column" />
-      </div>
-    </section >
-    {onClose &&
-      <section class="section is-main-section">
-        <button
-          class="button"
-          onClick={onClose}
-        >
-          <i18n.Translate>Close</i18n.Translate>
-        </button>
       </section>
-    }
-  </div >
-}
\ No newline at end of file
+      {onClose && (
+        <section class="section is-main-section">
+          <button class="button" onClick={onClose}>
+            <i18n.Translate>Close</i18n.Translate>
+          </button>
+        </section>
+      )}
+    </div>
+  );
+}
diff --git a/packages/merchant-backoffice-ui/src/schemas/index.ts 
b/packages/merchant-backoffice-ui/src/schemas/index.ts
index 5d168d6ac..693894ae0 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
@@ -19,10 +19,10 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { Amounts } from "@gnu-taler/taler-util";
 import { isAfter, isFuture } from "date-fns";
 import * as yup from "yup";
-import { AMOUNT_REGEX, PAYTO_REGEX } from "../utils/constants.js";
-import { Amounts } from "@gnu-taler/taler-util";
+import { PAYTO_REGEX } from "../utils/constants.js";
 
 yup.setLocale({
   mixed: {
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..c94101b4b 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
@@ -17,8 +17,8 @@ import {
   amountFractionalBase,
   AmountJson,
   Amounts,
+  TalerMerchantApi,
 } from "@gnu-taler/taler-util";
-import { MerchantBackend } from "../declaration.js";
 
 /**
  * merge refund with the same description and a difference less than one minute
@@ -27,9 +27,9 @@ import { MerchantBackend } from "../declaration.js";
  * @returns list with the new refund, may be merged with the last
  */
 export function mergeRefunds(
-  prev: MerchantBackend.Orders.RefundDetails[],
-  cur: MerchantBackend.Orders.RefundDetails,
-): MerchantBackend.Orders.RefundDetails[] {
+  prev: TalerMerchantApi.RefundDetails[],
+  cur: TalerMerchantApi.RefundDetails,
+): TalerMerchantApi.RefundDetails[] {
   let tail;
 
   if (
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..982b68e5e 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
@@ -14,7 +14,6 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { WithId } from "../declaration.js";
 
 /**
  *
diff --git a/packages/merchant-backoffice-ui/src/utils/types.ts 
b/packages/merchant-backoffice-ui/src/utils/types.ts
index 0d249f3c4..9ce6da4d1 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
@@ -23,7 +23,7 @@ export interface KeyValue {
 export interface Notification {
   message: string;
   description?: string | VNode;
-  details?: string | VNode;
+  details?: string | VNode | string;
   type: MessageType;
 }
 
diff --git a/packages/taler-harness/create_merchantAndBankAccount_pdf.sh 
b/packages/taler-harness/create_merchantAndBankAccount_pdf.sh
new file mode 100644
index 000000000..4593cc9a0
--- /dev/null
+++ b/packages/taler-harness/create_merchantAndBankAccount_pdf.sh
@@ -0,0 +1,23 @@
+DATA=$(mktemp)
+set -e
+
+[ -z "$1" ] && echo First parameter must be the json file result from 
\'taler-harness deployment provision-bank-and-merchant\'. Alternative \'-\' can 
be used if the file is provided from stdin. && exit 1
+
+cat $1 > $DATA
+
+[ -z "$(jq -r '.bankUser//empty' $DATA)" ] && echo the json file is not 
complete: missing bankUser && exit 1
+[ -z "$(jq -r '.bankURL//empty' $DATA)" ] && echo the json file is not 
complete: missing bankURL && exit 1
+[ -z "$(jq -r '.merchantURL//empty' $DATA)" ] && echo the json file is not 
complete: missing merchantURL && exit 1
+[ -z "$(jq -r '.templateURI//empty' $DATA)" ] && echo the json file is not 
complete: missing templateURI && exit 1
+[ -z "$(jq -r '.password//empty' $DATA)" ] && echo the json file is not 
complete: missing password && exit 1
+
+add_qr_image(){
+  jq -r $1 $DATA | qrencode -l Q -m 2 -s 5 -o - | base64 -w 0 | jq -Rn 
'{"'$2'":inputs}' | jq -s add - $DATA | sponge $DATA
+}
+
+add_qr_image .templateURI templateQR
+add_qr_image .bankURL bankQR
+add_qr_image .merchantURL merchantQR
+
+chevron pdf-template.html -d $DATA | wkhtmltopdf - out.pdf
+
diff --git a/packages/taler-harness/pdf-template.html 
b/packages/taler-harness/pdf-template.html
new file mode 100644
index 000000000..d308d67c4
--- /dev/null
+++ b/packages/taler-harness/pdf-template.html
@@ -0,0 +1,65 @@
+<html>
+
+<body style="padding: 3em">
+  <h1 id="account-information">Account information</h1>
+
+  <p>The information in this page is confidentail, do not share with 
others.</p>
+
+  <h2 style="margin-top: 4em;" id="bank-account">Bank</h2>
+  <p>
+    In your bank account you will be able to see how much revenue
+    has been consolidated.
+  </p>
+  <div style="display: flex; justify-content: space-between;">
+
+    <div>
+      <p>URL: {{bankURL}}</p>
+      <p>accounts id: {{bankUser}}</p>
+      <p>password: {{password}}</p>
+    </div>
+
+    <div>
+      <figure style="text-align: center;">
+        <img src="data:image/png;base64,{{bankQR}}" alt="" />
+        <figcaption>bank URL</figcaption>
+      </figure>
+    </div>
+  </div>
+
+  <hr />
+
+  <h2 style="margin-top: 4em;" id="merchant-instance">Backoffice</h2>
+  <p>
+    In this site you will be able to see how much are you selling,
+    make refunds or create new QR codes.
+  </p>
+
+  <div style="display: flex; justify-content: space-between;">
+    <div>
+      <p>URL: {{merchantURL}}</p>
+      <p>password: {{password}}</p>
+    </div>
+    <div>
+      <figure style="text-align: center;">
+        <img src="data:image/png;base64,{{merchantQR}}" alt="" />
+        <figcaption>merchant URL</figcaption>
+      </figure>
+    </div>
+  </div>
+
+  <hr />
+  <div style="page-break-after: always;">
+
+  </div>
+  <h1 style="margin-top: 4em;" id="template">Payme QR code</h1>
+  <p>
+    The following QR code can be utilized in
+    public settings to request payments.
+  </p>
+  <figure style="text-align: center;">
+    <img src="data:image/png;base64,{{templateQR}}" alt="" />
+    <figcaption>{{templateURI}}</figcaption>
+  </figure>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/packages/taler-harness/src/index.ts 
b/packages/taler-harness/src/index.ts
index 3bec1698a..4b0319a3e 100644
--- a/packages/taler-harness/src/index.ts
+++ b/packages/taler-harness/src/index.ts
@@ -18,6 +18,7 @@
  * Imports.
  */
 import {
+  AccessToken,
   AmountString,
   Amounts,
   BalancesResponse,
@@ -25,14 +26,23 @@ import {
   Duration,
   HttpStatusCode,
   Logger,
-  MerchantInstanceConfig,
-  RegisterAccountRequest,
+  PaytoString,
+  TalerAuthenticationHttpClient,
+  TalerBankConversionHttpClient,
+  TalerCoreBankHttpClient,
+  TalerErrorCode,
+  TalerMerchantInstanceHttpClient,
+  TalerMerchantManagementHttpClient,
   TransactionsResponse,
   decodeCrock,
+  encodeCrock,
   generateIban,
   j2s,
+  randomBytes,
   rsaBlind,
   setGlobalLogLevelFromString,
+  setPrintHttpRequestAsCurl,
+  stringifyPayTemplateUri
 } from "@gnu-taler/taler-util";
 import { clk } from "@gnu-taler/taler-util/clk";
 import {
@@ -69,6 +79,7 @@ import {
 } from "./harness/helpers.js";
 import { getTestInfo, runTests } from "./integrationtests/testrunner.js";
 import { lintExchangeDeployment } from "./lint.js";
+import { randomUUID } from "crypto";
 
 const logger = new Logger("taler-harness:index.ts");
 
@@ -585,6 +596,291 @@ deploymentCli
     console.log(generateIban(args.genIban.countryCode, args.genIban.length));
   });
 
+deploymentCli
+  .subcommand("provisionBankMerchant", "provision-bank-and-merchant", {
+    help: "Provision a bank account, merchant instance and link them 
together.",
+  })
+  .requiredArgument("merchantApiBaseUrl", clk.STRING, {
+    help: "URL location of the merchant backend"
+  })
+  .requiredArgument("corebankApiBaseUrl", clk.STRING, {
+    help: "URL location of the libeufin bank backend"
+  })
+  .requiredOption("merchantToken", ["--merchant-management-token"], 
clk.STRING, {
+    help: "acces token of the default instance in the merchant backend"
+  })
+  .maybeOption("bankToken", ["--bank-admin-token"], clk.STRING, {
+    help: "libeufin bank admin's password if the account creation is 
restricted"
+  })
+  .requiredOption("name", ["--legal-name"], clk.STRING, {
+    help: "legal name of the merchant"
+  })
+  .maybeOption("email", ["--email"], clk.STRING, {
+    help: "email contact of the merchant"
+  })
+  .maybeOption("phone", ["--phone"], clk.STRING, {
+    help: "phone contact of the merchant"
+  })
+  .requiredOption("id", ["--id"], clk.STRING, {
+    help: "login id for the bank account and instance id of the merchant 
backend"
+  })
+  .flag("template", ["--create-template"], {
+    help: "use this flag to create a default template for the merchant with 
fixed summary"
+  })
+  .requiredOption("password", ["--password"], clk.STRING, {
+    help: "password of the accounts in libeufin bank and merchant backend"
+  })
+  .flag("randomPassword", ["--set-random-password"], {
+    help: "if everything worked ok, change the password of the accounts at the 
end"
+  })
+  .action(async (args) => {
+    const managementToken = args.provisionBankMerchant.merchantToken as 
AccessToken;
+    const bankAdminPassword = args.provisionBankMerchant.bankToken as 
AccessToken;
+    const id = args.provisionBankMerchant.id;
+    const name = args.provisionBankMerchant.name;
+    const email = args.provisionBankMerchant.email;
+    const phone = args.provisionBankMerchant.phone;
+    const password = args.provisionBankMerchant.password;
+
+
+    const httpLib = createPlatformHttpLib({});
+    const merchantManager = new 
TalerMerchantManagementHttpClient(args.provisionBankMerchant.merchantApiBaseUrl,
 httpLib);
+    const bank = new 
TalerCoreBankHttpClient(args.provisionBankMerchant.corebankApiBaseUrl, httpLib);
+    const instanceURL = merchantManager.getSubInstanceAPI(id).href
+    const merchantInstance = new TalerMerchantInstanceHttpClient(instanceURL, 
httpLib);
+    const conv = new 
TalerBankConversionHttpClient(bank.getConversionInfoAPI().href, httpLib)
+    const bankAuth = new 
TalerAuthenticationHttpClient(bank.getAuthenticationAPI(id).href, httpLib)
+
+
+    const bc = await bank.getConfig()
+    if (!bank.isCompatible(bc.body.version)) {
+      logger.error(
+        `bank server version is not compatible: ${bc.body.version}, client 
version: ${bank.PROTOCOL_VERSION}`,
+      );
+      return;
+    }
+    const mc = await merchantManager.getConfig()
+    if (!merchantManager.isCompatible(mc.body.version)) {
+      logger.error(
+        `merchant server version is not compatible: ${mc.body.version}, client 
version: ${merchantManager.PROTOCOL_VERSION}`,
+      );
+      return;
+    }
+
+    /**
+     * create bank account
+     */
+    let accountPayto: PaytoString;
+    {
+      const resp = await bank.createAccount(bankAdminPassword, {
+        name: name,
+        password: password,
+        username: id,
+        contact_data: email || phone ? {
+          email: email,
+          phone: phone,
+        } : undefined,
+      })
+
+      if (resp.type === "fail") {
+        logger.error(`unable to provision bank account, HTTP response status 
${resp.case}`);
+        process.exit(2);
+      }
+      logger.info(`account ${id} successfully provisioned`);
+      accountPayto = resp.body.internal_payto_uri
+    }
+
+    /**
+     * create merchant account
+     */
+    {
+      const resp = await merchantManager.createInstance(managementToken, {
+        address: {},
+        auth: {
+          method: "token",
+          token: `secret-token:${password}`,
+        },
+        default_pay_delay: Duration.toTalerProtocolDuration(
+          Duration.fromSpec({ hours: 1 }),
+        ),
+        default_wire_transfer_delay: Duration.toTalerProtocolDuration(
+          Duration.fromSpec({ hours: 1 }),
+        ),
+        id: id,
+        jurisdiction: {},
+        name: name,
+        use_stefan: true,
+      })
+
+      if (resp.type === "ok") {
+        logger.info(`instance ${id} created successfully`);
+      } else if (resp.case === HttpStatusCode.Conflict) {
+        logger.info(`instance ${id} already exists`);
+      } else {
+        logger.error(
+          `unable to create instance ${id}, HTTP status ${resp.case}`,
+        );
+        process.exit(2);
+      }
+    }
+
+    let wireAccount: string;
+    /**
+     * link bank account and merchant
+     */
+    {
+      const resp = await merchantInstance.addAccount(password as AccessToken, {
+        payto_uri: accountPayto,
+        credit_facade_url: bank.getRevenueAPI(id).href,
+        credit_facade_credentials: {
+          type: "basic",
+          username: id,
+          password: password,
+        }
+      })
+      if (resp.type === "fail") {
+        console.error(`unable to configure bank account for instance ${id}, 
status ${resp.case}`)
+        console.error(j2s(resp.detail));
+        process.exit(2);
+      }
+      wireAccount = resp.body.h_wire
+    }
+
+    logger.info(`successfully configured bank account for ${id}`);
+
+    let templateURI;
+    /**
+     * create template
+     */
+    if (args.provisionBankMerchant.template) {
+      let currency = bc.body.currency;
+      if (bc.body.allow_conversion) {
+        const cc = await conv.getConfig();
+        if (cc.type === "ok") {
+          currency = cc.body.fiat_currency
+        } else {
+          console.error(
+            `could not get fiat currency status ${cc.case}`,
+          );
+          console.error(j2s(cc.detail));
+        }
+      } else {
+        console.log(`conversion is disabled, using bank currency`)
+      }
+
+      {
+        const resp = await merchantInstance.addTemplate(password as 
AccessToken, {
+          template_id: "default",
+          template_description: "First template",
+          template_contract: {
+            pay_duration: Duration.toTalerProtocolDuration(
+              Duration.fromSpec({ hours: 1 }),
+            ),
+            minimum_age: 0,
+            currency,
+            summary: "Pay me!"
+          }
+        })
+        if (resp.type === "fail") {
+          console.error(`unable to create template for insntaince ${id}, 
status ${resp.case}`)
+          console.error(j2s(resp.detail));
+          process.exit(2);
+        }
+      }
+
+      logger.info(`template default successfully created`);
+      templateURI = stringifyPayTemplateUri({
+        merchantBaseUrl: instanceURL,
+        templateId: "default",
+        templateParams: {
+          amount: currency
+        }
+      })
+    }
+
+    let finalPassword = password;
+    if (args.provisionBankMerchant.randomPassword) {
+      const prevPassword = password as AccessToken
+      const randomPassword = encodeCrock(randomBytes(16));
+      logger.info("random password: ", randomPassword)
+      let token: AccessToken;
+      {
+        const resp = await bankAuth.createAccessTokenBasic(id, prevPassword, {
+          scope: "readwrite",
+          duration: Duration.toTalerProtocolDuration(Duration.fromSpec({ 
minutes: 1 })),
+          refreshable: false,
+        })
+        if (resp.type === "fail") {
+          console.error(`unable to login into bank accountfor user ${id}, 
status ${resp.case}`)
+          console.error(j2s(resp.detail));
+          process.exit(2);
+        }
+        token = resp.body.access_token;
+      }
+
+      {
+        const resp = await bank.updatePassword({ username: id, token }, {
+          old_password: prevPassword,
+          new_password: randomPassword,
+        });
+        if (resp.type === "fail") {
+          console.error(`unable to change bank pasword for user ${id}, status 
${resp.case}`)
+          if (resp.case !== HttpStatusCode.Accepted) {
+            console.error(j2s(resp.detail));
+          } else {
+            console.error("2FA required")
+          }
+          process.exit(2);
+        }
+      }
+
+      {
+        const resp = await 
merchantInstance.updateCurrentInstanceAuthentication(prevPassword, {
+          method: "token",
+          token: `secret-token:${randomPassword}` as AccessToken
+        })
+        if (resp.type === "fail") {
+          console.error(`unable to change merchant password for instance 
${id}, status ${resp.case}`)
+          console.error(j2s(resp.detail));
+          process.exit(2);
+        }
+      }
+
+      {
+        const resp = await merchantInstance.updateAccount(randomPassword as 
AccessToken, wireAccount, {
+          credit_facade_url: bank.getRevenueAPI(id).href,
+          credit_facade_credentials: {
+            type: "basic",
+            username: id,
+            password: randomPassword,
+          }
+        })
+        if (resp.type != "ok") {
+          console.error(
+            `unable to update bank account for instance ${id}, status 
${resp.case}`,
+          );
+          console.error(j2s(resp.detail));
+          process.exit(2);
+        }
+      }
+      finalPassword = randomPassword;
+    }
+    logger.info(`successfully configured bank account for ${id}`);
+
+    /**
+     * show result
+     */
+    console.log(JSON.stringify({
+      bankUser: id,
+      bankURL: args.provisionBankMerchant.corebankApiBaseUrl,
+      merchantURL: instanceURL,
+      templateURI,
+      password: finalPassword,
+    }, undefined, 2))
+
+  });
+
+
 deploymentCli
   .subcommand("provisionMerchantInstance", "provision-merchant-instance", {
     help: "Provision a merchant backend instance.",
@@ -595,17 +891,27 @@ deploymentCli
   .requiredOption("name", ["--name"], clk.STRING)
   .requiredOption("id", ["--id"], clk.STRING)
   .requiredOption("payto", ["--payto"], clk.STRING)
+  .maybeOption("bankURL", ["--bankURL"], clk.STRING)
+  .maybeOption("bankUser", ["--bankUser"], clk.STRING)
+  .maybeOption("bankPassword", ["--bankPassword"], clk.STRING)
   .action(async (args) => {
-    const httpLib = createPlatformHttpLib();
+    const httpLib = createPlatformHttpLib({});
     const baseUrl = args.provisionMerchantInstance.merchantApiBaseUrl;
-    const managementToken = args.provisionMerchantInstance.managementToken;
-    const instanceToken = args.provisionMerchantInstance.instanceToken;
+    const api = new TalerMerchantManagementHttpClient(baseUrl, httpLib)
+    const managementToken = args.provisionMerchantInstance.managementToken as 
AccessToken;
+    const instanceToken = args.provisionMerchantInstance.instanceToken as 
AccessToken;
     const instanceId = args.provisionMerchantInstance.id;
-    const body: MerchantInstanceConfig = {
+    const instancceName = args.provisionMerchantInstance.name;
+    const bankURL = args.provisionMerchantInstance.bankURL;
+    const bankUser = args.provisionMerchantInstance.bankUser;
+    const bankPassword = args.provisionMerchantInstance.bankPassword;
+    const accountPayto = args.provisionMerchantInstance.payto as PaytoString;
+
+    const createResp = await api.createInstance(managementToken, {
       address: {},
       auth: {
         method: "token",
-        token: args.provisionMerchantInstance.instanceToken,
+        token: `secret-token:${instanceToken}`,
       },
       default_pay_delay: Duration.toTalerProtocolDuration(
         Duration.fromSpec({ hours: 1 }),
@@ -613,48 +919,35 @@ deploymentCli
       default_wire_transfer_delay: { d_us: 1 },
       id: instanceId,
       jurisdiction: {},
-      name: args.provisionMerchantInstance.name,
+      name: instancceName,
       use_stefan: true,
-    };
-    const url = new URL("management/instances", baseUrl);
-    const createResp = await httpLib.fetch(url.href, {
-      method: "POST",
-      body,
-      headers: {
-        Authorization: `Bearer ${managementToken}`,
-      },
-    });
-    if (createResp.status >= 200 && createResp.status <= 299) {
+    })
+
+    if (createResp.type === "ok") {
       logger.info(`instance ${instanceId} created successfully`);
-    } else if (createResp.status === HttpStatusCode.Conflict) {
+    } else if (createResp.case === HttpStatusCode.Conflict) {
       logger.info(`instance ${instanceId} already exists`);
     } else {
       logger.error(
-        `unable to create instance ${instanceId}, HTTP status 
${createResp.status}`,
+        `unable to create instance ${instanceId}, HTTP status 
${createResp.case}`,
       );
       process.exit(2);
     }
 
-    const accountsUrl = new URL(
-      `instances/${instanceId}/private/accounts`,
-      baseUrl,
-    );
-    const accountBody = {
-      payto_uri: args.provisionMerchantInstance.payto,
-    };
-    const createAccountResp = await httpLib.fetch(accountsUrl.href, {
-      method: "POST",
-      body: accountBody,
-      headers: {
-        Authorization: `Bearer ${instanceToken}`,
-      },
-    });
-    if (createAccountResp.status != 200) {
+    const createAccountResp = await api.addAccount(instanceToken, {
+      payto_uri: accountPayto,
+      credit_facade_url: bankURL,
+      credit_facade_credentials: bankUser && bankPassword ? {
+        type: "basic",
+        username: bankUser,
+        password: bankPassword,
+      } : undefined
+    })
+    if (createAccountResp.type != "ok") {
       console.error(
-        `unable to configure bank account for instance ${instanceId}, status 
${createAccountResp.status}`,
+        `unable to configure bank account for instance ${instanceId}, status 
${createAccountResp.case}`,
       );
-      const resp = await createAccountResp.json();
-      console.error(j2s(resp));
+      console.error(j2s(createAccountResp.detail));
       process.exit(2);
     }
     logger.info(`successfully configured bank account for ${instanceId}`);
@@ -673,31 +966,25 @@ deploymentCli
   .maybeOption("internalPayto", ["--payto"], clk.STRING)
   .action(async (args) => {
     const httpLib = createPlatformHttpLib();
-    const corebankApiBaseUrl = args.provisionBankAccount.corebankApiBaseUrl;
-    const url = new URL("accounts", corebankApiBaseUrl);
+    const baseUrl = args.provisionBankAccount.corebankApiBaseUrl;
+    const api = new TalerCoreBankHttpClient(baseUrl, httpLib);
+
     const accountLogin = args.provisionBankAccount.login;
-    const body: RegisterAccountRequest = {
+    const resp = await api.createAccount(undefined, {
       name: args.provisionBankAccount.name,
       password: args.provisionBankAccount.password,
       username: accountLogin,
       is_public: !!args.provisionBankAccount.public,
       is_taler_exchange: !!args.provisionBankAccount.exchange,
-      payto_uri: args.provisionBankAccount.internalPayto,
-    };
-    const resp = await httpLib.fetch(url.href, {
-      method: "POST",
-      body,
-    });
-    if (resp.status >= 200 && resp.status <= 299) {
+      payto_uri: args.provisionBankAccount.internalPayto as PaytoString,
+    })
+
+    if (resp.type === "ok") {
       logger.info(`account ${accountLogin} successfully provisioned`);
       return;
     }
-    if (resp.status === HttpStatusCode.Conflict) {
-      logger.info(`account ${accountLogin} already provisioned`);
-      return;
-    }
     logger.error(
-      `unable to provision bank account, HTTP response status ${resp.status}`,
+      `unable to provision bank account, HTTP response status ${resp.case}`,
     );
     process.exit(2);
   });
diff --git a/packages/taler-util/src/http-client/authentication.ts 
b/packages/taler-util/src/http-client/authentication.ts
index e8ef6a274..f77df2ed0 100644
--- a/packages/taler-util/src/http-client/authentication.ts
+++ b/packages/taler-util/src/http-client/authentication.ts
@@ -34,6 +34,7 @@ import {
   AccessToken,
   TalerAuthentication,
   codecForTokenSuccessResponse,
+  codecForTokenSuccessResponseMerchant,
 } from "./types.js";
 import { makeBearerTokenAuthHeader } from "./utils.js";
 
@@ -44,7 +45,6 @@ export class TalerAuthenticationHttpClient {
 
   constructor(
     readonly baseUrl: string,
-    readonly username: string,
     httpClient?: HttpRequestLibrary,
   ) {
     this.httpLib = httpClient ?? createPlatformHttpLib();
@@ -60,7 +60,8 @@ export class TalerAuthenticationHttpClient {
    *
    * @returns
    */
-  async createAccessToken(
+  async createAccessTokenBasic(
+    username: string,
     password: string,
     body: TalerAuthentication.TokenRequest,
   ) {
@@ -68,7 +69,7 @@ export class TalerAuthenticationHttpClient {
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       headers: {
-        Authorization: makeBasicAuthHeader(this.username, password),
+        Authorization: makeBasicAuthHeader(username, password),
       },
       body,
     });
@@ -85,6 +86,35 @@ export class TalerAuthenticationHttpClient {
     }
   }
 
+  /**
+   *
+   * @returns
+   */
+  async createAccessTokenBearer(
+    token: string,
+    body: TalerAuthentication.TokenRequest,
+  ) {
+    const url = new URL(`token`, this.baseUrl);
+    const resp = await this.httpLib.fetch(url.href, {
+      method: "POST",
+      headers: {
+        Authorization: makeBearerTokenAuthHeader(token as AccessToken),
+      },
+      body,
+    });
+    switch (resp.status) {
+      case HttpStatusCode.Ok:
+        return opSuccessFromHttp(resp, codecForTokenSuccessResponseMerchant());
+      //FIXME: missing in docs
+      case HttpStatusCode.Unauthorized:
+        return opKnownHttpFailure(resp.status, resp);
+      case HttpStatusCode.NotFound:
+        return opKnownHttpFailure(resp.status, resp);
+      default:
+        return opUnknownFailure(resp, await resp.text());
+    }
+  }
+
   async deleteAccessToken(token: AccessToken) {
     const url = new URL(`token`, this.baseUrl);
     const resp = await this.httpLib.fetch(url.href, {
diff --git a/packages/taler-util/src/http-client/bank-core.ts 
b/packages/taler-util/src/http-client/bank-core.ts
index c02bf1ec9..7a98b6281 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,
@@ -140,16 +140,18 @@ export class TalerCoreBankHttpClient {
    *
    */
   async createAccount(
-    auth: AccessToken,
+    auth: AccessToken | undefined,
     body: TalerCorebankApi.RegisterAccountRequest,
   ) {
     const url = new URL(`accounts`, this.baseUrl);
+    const headers: Record<string, string> = {}
+    if (auth) {
+      headers.Authorization = makeBearerTokenAuthHeader(auth)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
-      headers: {
-        Authorization: makeBearerTokenAuthHeader(auth),
-      },
+      headers: headers,
     });
     switch (resp.status) {
       case HttpStatusCode.Ok: {
diff --git a/packages/taler-util/src/http-client/merchant.ts 
b/packages/taler-util/src/http-client/merchant.ts
index 886844dba..394625e38 100644
--- a/packages/taler-util/src/http-client/merchant.ts
+++ b/packages/taler-util/src/http-client/merchant.ts
@@ -15,6 +15,7 @@
  */
 
 import {
+  AccessToken,
   HttpStatusCode,
   LibtoolVersion,
   PaginationParams,
@@ -64,12 +65,16 @@ import { opSuccessFromHttp, opUnknownFailure } from 
"../operation.js";
 import {
   CacheEvictor,
   addMerchantPaginationParams,
+  makeBearerTokenAuthHeader,
   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 +88,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;
@@ -105,6 +110,7 @@ export class TalerMerchantInstanceHttpClient {
    */
   async getConfig() {
     const url = new URL(`config`, this.baseUrl);
+
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
     });
@@ -333,19 +339,26 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-auth
    */
   async updateCurrentInstanceAuthentication(
+    token: AccessToken | undefined,
     body: TalerMerchantApi.InstanceAuthConfigurationMessage,
   ) {
     const url = new URL(`private/auth`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
 
-    //
     switch (resp.status) {
       case HttpStatusCode.Ok:
         return opEmptySuccess(resp);
+      case HttpStatusCode.NoContent: // FIXME: missing in docs
+        return opEmptySuccess(resp);
       case HttpStatusCode.NotFound:
         return opKnownHttpFailure(resp.status, resp);
       default:
@@ -353,27 +366,23 @@ 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
    */
   async updateCurrentInstance(
+    token: AccessToken | undefined,
     body: TalerMerchantApi.InstanceReconfigurationMessage,
   ) {
     const url = new URL(`private`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "PATCH",
       body,
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.Ok:
@@ -389,11 +398,16 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private
    *
    */
-  async getCurrentInstance() {
+  async getCurrentInstance(token: AccessToken) {
     const url = new URL(`private`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -407,15 +421,20 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private
    */
-  async deleteCurrentInstance(params: { purge?: boolean }) {
+  async deleteCurrentInstance(token: AccessToken | undefined, params: { 
purge?: boolean }) {
     const url = new URL(`private`, this.baseUrl);
 
     if (params.purge) {
       url.searchParams.set("purge", "YES");
     }
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "DELETE",
+      headers,
     });
 
     switch (resp.status) {
@@ -436,6 +455,7 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#get--instances-$INSTANCE-private-kyc
    */
   async getCurrentIntanceKycStatus(
+    token: AccessToken | undefined,
     params: TalerMerchantApi.GetKycStatusRequestParams,
   ) {
     const url = new URL(`private/kyc`, this.baseUrl);
@@ -450,8 +470,13 @@ export class TalerMerchantInstanceHttpClient {
       url.searchParams.set("timeout_ms", String(params.timeout));
     }
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -477,12 +502,17 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-accounts
    */
-  async addAccount(body: TalerMerchantApi.AccountAddDetails) {
+  async addAccount(token: AccessToken | undefined, body: 
TalerMerchantApi.AccountAddDetails) {
     const url = new URL(`private/accounts`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
 
     switch (resp.status) {
@@ -501,14 +531,20 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-accounts-$H_WIRE
    */
   async updateAccount(
+    token: AccessToken | undefined,
     wireAccount: string,
     body: TalerMerchantApi.AccountPatchDetails,
   ) {
     const url = new URL(`private/accounts/${wireAccount}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "PATCH",
       body,
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.NoContent:
@@ -523,11 +559,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-accounts
    */
-  async listAccounts() {
+  async listAccounts(token: AccessToken) {
     const url = new URL(`private/accounts`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -543,11 +584,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-accounts-$H_WIRE
    */
-  async getAccount(wireAccount: string) {
+  async getAccount(token: AccessToken | undefined, wireAccount: string) {
     const url = new URL(`private/accounts/${wireAccount}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -563,11 +609,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-accounts-$H_WIRE
    */
-  async deleteAccount(wireAccount: string) {
+  async deleteAccount(token: AccessToken | undefined, wireAccount: string) {
     const url = new URL(`private/accounts/${wireAccount}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "DELETE",
+      headers,
     });
 
     switch (resp.status) {
@@ -587,12 +638,17 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-products
    */
-  async addProduct(body: TalerMerchantApi.ProductAddDetail) {
+  async addProduct(token: AccessToken | undefined, body: 
TalerMerchantApi.ProductAddDetail) {
     const url = new URL(`private/products`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
 
     switch (resp.status) {
@@ -609,14 +665,20 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-products-$PRODUCT_ID
    */
   async updateProduct(
+    token: AccessToken | undefined,
     productId: string,
     body: TalerMerchantApi.ProductAddDetail,
   ) {
     const url = new URL(`private/products/${productId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "PATCH",
       body,
+      headers,
     });
 
     switch (resp.status) {
@@ -634,13 +696,18 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-products
    */
-  async listProducts(params?: PaginationParams) {
+  async listProducts(token: AccessToken | undefined, params?: 
PaginationParams) {
     const url = new URL(`private/products`, this.baseUrl);
 
     addMerchantPaginationParams(url, params);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -656,11 +723,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-products-$PRODUCT_ID
    */
-  async getProduct(productId: string) {
+  async getProduct(token: AccessToken | undefined, productId: string) {
     const url = new URL(`private/products/${productId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -676,11 +748,17 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * https://docs.taler.net/core/api-merchant.html#reserving-inventory
    */
-  async lockProduct(productId: string) {
+  async lockProduct(token: AccessToken | undefined, productId: string, body: 
TalerMerchantApi.LockRequest) {
     const url = new URL(`private/products/${productId}/lock`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
+      body,
+      headers,
     });
 
     switch (resp.status) {
@@ -698,11 +776,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#removing-products-from-inventory
    */
-  async removeProduct(productId: string) {
+  async removeProduct(token: AccessToken | undefined, productId: string) {
     const url = new URL(`private/products/${productId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "DELETE",
+      headers,
     });
 
     switch (resp.status) {
@@ -724,20 +807,27 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-orders
    */
-  async createOrder(body: TalerMerchantApi.PostOrderRequest) {
+  async createOrder(token: AccessToken | undefined, body: 
TalerMerchantApi.PostOrderRequest) {
     const url = new URL(`private/orders`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
-    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:
@@ -756,7 +846,7 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * https://docs.taler.net/core/api-merchant.html#inspecting-orders
    */
-  async listOrders(params: TalerMerchantApi.ListOrdersRequestParams = {}) {
+  async listOrders(token: AccessToken | undefined, params: 
TalerMerchantApi.ListOrdersRequestParams = {}) {
     const url = new URL(`private/orders`, this.baseUrl);
 
     if (params.date) {
@@ -782,8 +872,13 @@ export class TalerMerchantInstanceHttpClient {
     }
     addMerchantPaginationParams(url, params);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -798,6 +893,7 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-orders-$ORDER_ID
    */
   async getOrder(
+    token: AccessToken | undefined,
     orderId: string,
     params: TalerMerchantApi.GetOrderRequestParams = {},
   ) {
@@ -813,8 +909,13 @@ export class TalerMerchantInstanceHttpClient {
       url.searchParams.set("timeout_ms", String(params.timeout));
     }
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -841,12 +942,17 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * https://docs.taler.net/core/api-merchant.html#private-order-data-cleanup
    */
-  async forgetOrder(orderId: string, body: TalerMerchantApi.ForgetRequest) {
+  async forgetOrder(token: AccessToken | undefined, orderId: string, body: 
TalerMerchantApi.ForgetRequest) {
     const url = new URL(`private/orders/${orderId}/forget`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "PATCH",
       body,
+      headers,
     });
 
     switch (resp.status) {
@@ -868,11 +974,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-orders-$ORDER_ID
    */
-  async deleteOrder(orderId: string) {
+  async deleteOrder(token: AccessToken | undefined, orderId: string) {
     const url = new URL(`private/orders/${orderId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "DELETE",
+      headers,
     });
 
     switch (resp.status) {
@@ -894,12 +1005,17 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-orders-$ORDER_ID-refund
    */
-  async addRefund(orderId: string, body: TalerMerchantApi.RefundRequest) {
+  async addRefund(token: AccessToken | undefined, orderId: string, body: 
TalerMerchantApi.RefundRequest) {
     const url = new URL(`private/orders/${orderId}/refund`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
 
     switch (resp.status) {
@@ -925,12 +1041,17 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-transfers
    */
-  async informWireTransfer(body: TalerMerchantApi.TransferInformation) {
+  async informWireTransfer(token: AccessToken | undefined, body: 
TalerMerchantApi.TransferInformation) {
     const url = new URL(`private/transfers`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
 
     switch (resp.status) {
@@ -949,6 +1070,7 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-transfers
    */
   async listWireTransfers(
+    token: AccessToken | undefined,
     params: TalerMerchantApi.ListWireTransferRequestParams = {},
   ) {
     const url = new URL(`private/transfers`, this.baseUrl);
@@ -967,8 +1089,13 @@ export class TalerMerchantInstanceHttpClient {
     }
     addMerchantPaginationParams(url, params);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -982,11 +1109,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-transfers-$TID
    */
-  async deleteWireTransfer(transferId: string) {
+  async deleteWireTransfer(token: AccessToken | undefined, transferId: string) 
{
     const url = new URL(`private/transfers/${transferId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "DELETE",
+      headers,
     });
 
     switch (resp.status) {
@@ -1008,12 +1140,17 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-otp-devices
    */
-  async addOtpDevice(body: TalerMerchantApi.OtpDeviceAddDetails) {
+  async addOtpDevice(token: AccessToken | undefined, body: 
TalerMerchantApi.OtpDeviceAddDetails) {
     const url = new URL(`private/otp-devices`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
 
     switch (resp.status) {
@@ -1030,14 +1167,20 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-otp-devices-$DEVICE_ID
    */
   async updateOtpDevice(
+    token: AccessToken | undefined,
     deviceId: string,
     body: TalerMerchantApi.OtpDevicePatchDetails,
   ) {
     const url = new URL(`private/otp-devices/${deviceId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "PATCH",
       body,
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.NoContent:
@@ -1054,11 +1197,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-otp-devices
    */
-  async listOtpDevices() {
+  async listOtpDevices(token: AccessToken | undefined,) {
     const url = new URL(`private/otp-devices`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.Ok:
@@ -1074,6 +1222,7 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-otp-devices-$DEVICE_ID
    */
   async getOtpDevice(
+    token: AccessToken | undefined,
     deviceId: string,
     params: TalerMerchantApi.GetOtpDeviceRequestParams = {},
   ) {
@@ -1085,8 +1234,13 @@ export class TalerMerchantInstanceHttpClient {
     if (params.price) {
       url.searchParams.set("price", params.price);
     }
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -1102,11 +1256,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-otp-devices-$DEVICE_ID
    */
-  async deleteOtpDevice(deviceId: string) {
+  async deleteOtpDevice(token: AccessToken | undefined, deviceId: string) {
     const url = new URL(`private/otp-devices/${deviceId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "DELETE",
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.NoContent:
@@ -1125,12 +1284,17 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-templates
    */
-  async addTemplate(body: TalerMerchantApi.TemplateAddDetails) {
+  async addTemplate(token: AccessToken | undefined, body: 
TalerMerchantApi.TemplateAddDetails) {
     const url = new URL(`private/templates`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.NoContent:
@@ -1146,14 +1310,20 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-templates-$TEMPLATE_ID
    */
   async updateTemplate(
+    token: AccessToken | undefined,
     templateId: string,
     body: TalerMerchantApi.TemplatePatchDetails,
   ) {
     const url = new URL(`private/templates/${templateId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "PATCH",
       body,
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.NoContent:
@@ -1170,11 +1340,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * https://docs.taler.net/core/api-merchant.html#inspecting-template
    */
-  async listTemplates() {
+  async listTemplates(token: AccessToken | undefined,) {
     const url = new URL(`private/templates`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.Ok:
@@ -1189,11 +1364,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-templates-$TEMPLATE_ID
    */
-  async getTemplate(templateId: string) {
+  async getTemplate(token: AccessToken | undefined, templateId: string) {
     const url = new URL(`private/templates/${templateId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.Ok:
@@ -1208,11 +1388,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-templates-$TEMPLATE_ID
    */
-  async deleteTemplate(templateId: string) {
+  async deleteTemplate(token: AccessToken | undefined, templateId: string) {
     const url = new URL(`private/templates/${templateId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "DELETE",
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.NoContent:
@@ -1257,7 +1442,7 @@ export class TalerMerchantInstanceHttpClient {
       body,
     });
 
-    return TalerMerchantInstanceHttpClient.procesOrderCreationResponse(resp);
+    return this.procesOrderCreationResponse(resp)
   }
 
   //
@@ -1267,12 +1452,17 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCES]-private-webhooks
    */
-  async addWebhook(body: TalerMerchantApi.WebhookAddDetails) {
+  async addWebhook(token: AccessToken | undefined, body: 
TalerMerchantApi.WebhookAddDetails) {
     const url = new URL(`private/webhooks`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
 
     switch (resp.status) {
@@ -1289,14 +1479,20 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCES]-private-webhooks-$WEBHOOK_ID
    */
   async updateWebhook(
+    token: AccessToken | undefined,
     webhookId: string,
     body: TalerMerchantApi.WebhookPatchDetails,
   ) {
     const url = new URL(`private/webhooks/${webhookId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "PATCH",
       body,
+      headers,
     });
 
     switch (resp.status) {
@@ -1314,11 +1510,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCES]-private-webhooks
    */
-  async listWebhooks() {
+  async listWebhooks(token: AccessToken | undefined,) {
     const url = new URL(`private/webhooks`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -1334,11 +1535,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCES]-private-webhooks-$WEBHOOK_ID
    */
-  async getWebhook(webhookId: string) {
+  async getWebhook(token: AccessToken | undefined, webhookId: string) {
     const url = new URL(`private/webhooks/${webhookId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.NoContent:
@@ -1353,11 +1559,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCES]-private-webhooks-$WEBHOOK_ID
    */
-  async removeWebhook(webhookId: string) {
+  async removeWebhook(token: AccessToken | undefined, webhookId: string) {
     const url = new URL(`private/webhooks/${webhookId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "DELETE",
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.NoContent:
@@ -1376,12 +1587,17 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCES]-private-tokenfamilies
    */
-  async createTokenFamily(body: TalerMerchantApi.TokenFamilyCreateRequest) {
+  async createTokenFamily(token: AccessToken | undefined, body: 
TalerMerchantApi.TokenFamilyCreateRequest) {
     const url = new URL(`private/tokenfamilies`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
 
     switch (resp.status) {
@@ -1398,14 +1614,20 @@ export class TalerMerchantInstanceHttpClient {
    * 
https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCES]-private-tokenfamilies-$TOKEN_FAMILY_SLUG
    */
   async updateTokenFamily(
+    token: AccessToken | undefined,
     tokenSlug: string,
     body: TalerMerchantApi.TokenFamilyUpdateRequest,
   ) {
     const url = new URL(`private/tokenfamilies/${tokenSlug}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.Ok:
@@ -1420,11 +1642,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCES]-private-tokenfamilies
    */
-  async listTokenFamilies() {
+  async listTokenFamilies(token: AccessToken | undefined,) {
     const url = new URL(`private/tokenfamilies`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -1440,11 +1667,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCES]-private-tokenfamilies-$TOKEN_FAMILY_SLUG
    */
-  async getTokenFamily(tokenSlug: string) {
+  async getTokenFamily(token: AccessToken | undefined, tokenSlug: string) {
     const url = new URL(`private/tokenfamilies/${tokenSlug}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -1460,11 +1692,16 @@ export class TalerMerchantInstanceHttpClient {
   /**
    * 
https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCES]-private-tokenfamilies-$TOKEN_FAMILY_SLUG
    */
-  async deleteTokenFamily(tokenSlug: string) {
+  async deleteTokenFamily(token: AccessToken | undefined, tokenSlug: string) {
     const url = new URL(`private/tokenfamilies/${tokenSlug}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "DELETE",
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.NoContent:
@@ -1475,19 +1712,33 @@ 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) {
-    return new URL(`instances/${instanceId}`, this.baseUrl);
+  getSubInstanceAPI(instanceId: string) {
+    return new URL(`instances/${instanceId}/`, this.baseUrl);
   }
 
   //
@@ -1497,17 +1748,25 @@ export class TalerMerchantManagementHttpClient extends 
TalerMerchantInstanceHttp
   /**
    * https://docs.taler.net/core/api-merchant.html#post--management-instances
    */
-  async createInstance(body: TalerMerchantApi.InstanceConfigurationMessage) {
+  async createInstance(token: AccessToken | undefined, body: 
TalerMerchantApi.InstanceConfigurationMessage) {
     const url = new URL(`management/instances`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
 
+
     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:
@@ -1519,13 +1778,20 @@ export class TalerMerchantManagementHttpClient extends 
TalerMerchantInstanceHttp
    * 
https://docs.taler.net/core/api-merchant.html#post--management-instances-$INSTANCE-auth
    */
   async updateInstanceAuthentication(
+    token: AccessToken | undefined,
+    instanceId: string,
     body: TalerMerchantApi.InstanceAuthConfigurationMessage,
   ) {
-    const url = new URL(`management/instances`, this.baseUrl);
+    const url = new URL(`management/instances/${instanceId}/auth`, 
this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "POST",
       body,
+      headers,
     });
 
     switch (resp.status) {
@@ -1542,14 +1808,20 @@ export class TalerMerchantManagementHttpClient extends 
TalerMerchantInstanceHttp
    * 
https://docs.taler.net/core/api-merchant.html#patch--management-instances-$INSTANCE
    */
   async updateInstance(
+    token: AccessToken | undefined,
     instanceId: string,
     body: TalerMerchantApi.InstanceReconfigurationMessage,
   ) {
     const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "PATCH",
       body,
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.NoContent:
@@ -1564,11 +1836,16 @@ export class TalerMerchantManagementHttpClient extends 
TalerMerchantInstanceHttp
   /**
    * https://docs.taler.net/core/api-merchant.html#get--management-instances
    */
-  async listInstances() {
+  async listInstances(token: AccessToken | undefined,) {
     const url = new URL(`management/instances`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -1583,11 +1860,16 @@ export class TalerMerchantManagementHttpClient extends 
TalerMerchantInstanceHttp
    * 
https://docs.taler.net/core/api-merchant.html#get--management-instances-$INSTANCE
    *
    */
-  async getInstance(instanceId: string) {
+  async getInstance(token: AccessToken | undefined, instanceId: string) {
     const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
 
     switch (resp.status) {
@@ -1601,15 +1883,20 @@ export class TalerMerchantManagementHttpClient extends 
TalerMerchantInstanceHttp
   /**
    * 
https://docs.taler.net/core/api-merchant.html#delete--management-instances-$INSTANCE
    */
-  async deleteInstance(instanceId: string, params: { purge?: boolean } = {}) {
+  async deleteInstance(token: AccessToken | undefined, instanceId: string, 
params: { purge?: boolean } = {}) {
     const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
 
     if (params.purge) {
       url.searchParams.set("purge", "YES");
     }
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "DELETE",
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.NoContent:
@@ -1629,6 +1916,7 @@ export class TalerMerchantManagementHttpClient extends 
TalerMerchantInstanceHttp
    * 
https://docs.taler.net/core/api-merchant.html#get--management-instances-$INSTANCE-kyc
    */
   async getIntanceKycStatus(
+    token: AccessToken | undefined,
     instanceId: string,
     params: TalerMerchantApi.GetKycStatusRequestParams,
   ) {
@@ -1644,8 +1932,13 @@ export class TalerMerchantManagementHttpClient extends 
TalerMerchantInstanceHttp
       url.searchParams.set("timeout_ms", String(params.timeout));
     }
 
+    const headers: Record<string, string> = {}
+    if (token) {
+      headers.Authorization = makeBearerTokenAuthHeader(token)
+    }
     const resp = await this.httpLib.fetch(url.href, {
       method: "GET",
+      headers,
     });
     switch (resp.status) {
       case HttpStatusCode.Accepted:
diff --git a/packages/taler-util/src/http-client/types.ts 
b/packages/taler-util/src/http-client/types.ts
index 05897614a..8578eecd4 100644
--- a/packages/taler-util/src/http-client/types.ts
+++ b/packages/taler-util/src/http-client/types.ts
@@ -221,6 +221,16 @@ export namespace TalerAuthentication {
     // Opque access token.
     access_token: AccessToken;
   }
+  export interface TokenSuccessResponseMerchant {
+    // Expiration determined by the server.
+    // Can be based on the token_duration
+    // from the request, but ultimately the
+    // server decides the expiration.
+    expiration: Timestamp;
+
+    // Opque access token.
+    token: AccessToken;
+  }
 }
 
 // DD51 https://docs.taler.net/design-documents/051-fractional-digits.html
@@ -254,6 +264,13 @@ export const codecForTokenSuccessResponse =
       .property("expiration", codecForTimestamp)
       .build("TalerAuthentication.TokenSuccessResponse");
 
+export const codecForTokenSuccessResponseMerchant =
+  (): Codec<TalerAuthentication.TokenSuccessResponseMerchant> =>
+    buildCodecForObject<TalerAuthentication.TokenSuccessResponseMerchant>()
+      .property("token", codecForAccessToken())
+      .property("expiration", codecForTimestamp)
+      .build("TalerAuthentication.TokenSuccessResponseMerchant");
+
 export const codecForCurrencySpecificiation =
   (): Codec<CurrencySpecification> =>
     buildCodecForObject<CurrencySpecification>()
@@ -3916,7 +3933,7 @@ export namespace TalerMerchantApi {
     // Minimum age buyer must have (in years).
     minimum_age?: Integer;
   }
-  interface LockRequest {
+  export interface LockRequest {
     // UUID that identifies the frontend performing the lock
     // Must be unique for the lifetime of the lock.
     lock_uuid: string;
@@ -3956,7 +3973,7 @@ export namespace TalerMerchantApi {
     // be used in case different UUIDs were used for different
     // products (i.e. in case the user started with multiple
     // shopping sessions that were combined during checkout).
-    lock_uuids: string[];
+    lock_uuids?: string[];
 
     // Should a token for claiming the order be generated?
     // False can make sense if the ORDER_ID is sufficiently
@@ -4988,7 +5005,7 @@ export namespace TalerMerchantApi {
   }
   // Delivery location, loosely modeled as a subset of
   // ISO20022's PostalAddress25.
-  interface Location {
+  export interface Location {
     // Nation with its own government.
     country?: string;
 
diff --git a/packages/taler-util/src/http-common.ts 
b/packages/taler-util/src/http-common.ts
index 3973e66fb..cc75debd5 100644
--- a/packages/taler-util/src/http-common.ts
+++ b/packages/taler-util/src/http-common.ts
@@ -440,6 +440,7 @@ export interface HttpLibArgs {
    * Only allow HTTPS connections, not plain http.
    */
   requireTls?: boolean;
+  printAsCurl?: boolean;
 }
 
 export function encodeBody(body: any): ArrayBuffer {
diff --git a/packages/taler-util/src/http-impl.node.ts 
b/packages/taler-util/src/http-impl.node.ts
index b5c87843f..8606bc451 100644
--- a/packages/taler-util/src/http-impl.node.ts
+++ b/packages/taler-util/src/http-impl.node.ts
@@ -119,8 +119,13 @@ export class HttpLibImpl implements HttpRequestLibrary {
       timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS;
     }
 
-    const requestHeadersMap = { ...getDefaultHeaders(method), ...opt?.headers 
};
-
+    const requestHeadersMap = getDefaultHeaders(method);
+    if (opt?.headers) {
+      Object.entries(opt?.headers).forEach(([key, value]) => {
+        if (value === undefined) return;
+        requestHeadersMap[key] = value
+      })
+    }
     logger.trace(`request timeout ${timeoutMs} ms`);
 
     let reqBody: ArrayBuffer | undefined;
diff --git a/packages/taler-util/src/http-impl.qtart.ts 
b/packages/taler-util/src/http-impl.qtart.ts
index 0be9f2c23..b4e4ebbe7 100644
--- a/packages/taler-util/src/http-impl.qtart.ts
+++ b/packages/taler-util/src/http-impl.qtart.ts
@@ -98,7 +98,13 @@ export class HttpLibImpl implements HttpRequestLibrary {
     }
 
     let data: ArrayBuffer | undefined = undefined;
-    const requestHeadersMap = { ...getDefaultHeaders(method), ...opt?.headers 
};
+    const requestHeadersMap = getDefaultHeaders(method);
+    if (opt?.headers) {
+      Object.entries(opt?.headers).forEach(([key, value]) => {
+        if (value === undefined) return;
+        requestHeadersMap[key] = value
+      })
+    }
     let headersList: string[] = [];
     for (let headerName of Object.keys(requestHeadersMap)) {
       headersList.push(`${headerName}: ${requestHeadersMap[headerName]}`);
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/taler-util/src/taler-types.ts 
b/packages/taler-util/src/taler-types.ts
index 6d317a98a..7cc703fd6 100644
--- a/packages/taler-util/src/taler-types.ts
+++ b/packages/taler-util/src/taler-types.ts
@@ -1431,6 +1431,7 @@ export const codecForMerchantContractTerms = (): 
Codec<MerchantContractTerms> =>
     .property("exchanges", codecForList(codecForExchangeHandle()))
     .property("products", codecOptional(codecForList(codecForProduct())))
     .property("extra", codecForAny())
+    .property("minimum_age", codecOptional(codecForNumber()))
     .build("MerchantContractTerms");
 
 export const codecForPeerContractTerms = (): Codec<PeerContractTerms> =>
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..bd0653451
--- /dev/null
+++ b/packages/web-util/src/context/bank-api.ts
@@ -0,0 +1,201 @@
+/*
+ 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,
+      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..a531a5958
--- /dev/null
+++ b/packages/web-util/src/context/merchant-api.ts
@@ -0,0 +1,224 @@
+/*
+ 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,
+    httpLib,
+  );
+  const impersonate = (instanceId: string) =>
+    new TalerAuthenticationHttpClient(
+      instance(instanceId).getAuthenticationAPI().href,
+      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/bank-ui/src/context/navigation.ts 
b/packages/web-util/src/context/navigation.ts
similarity index 86%
copy from packages/bank-ui/src/context/navigation.ts
copy to packages/web-util/src/context/navigation.ts
index 9552bf899..a2fe3ff12 100644
--- a/packages/bank-ui/src/context/navigation.ts
+++ b/packages/web-util/src/context/navigation.ts
@@ -16,7 +16,17 @@
 
 import { ComponentChildren, createContext, h, VNode } from "preact";
 import { useContext, useEffect, useState } from "preact/hooks";
-import { AppLocation } from "../route.js";
+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);
+}
 
 /**
  *
diff --git a/packages/bank-ui/src/context/wallet-integration.ts 
b/packages/web-util/src/context/wallet-integration.ts
similarity index 100%
copy from packages/bank-ui/src/context/wallet-integration.ts
copy to packages/web-util/src/context/wallet-integration.ts
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/bank-ui/src/route.ts 
b/packages/web-util/src/utils/route.ts
similarity index 82%
copy from packages/bank-ui/src/route.ts
copy to packages/web-util/src/utils/route.ts
index 11f13d140..4f8a020f6 100644
--- a/packages/bank-ui/src/route.ts
+++ b/packages/web-util/src/utils/route.ts
@@ -13,7 +13,6 @@
  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 { useNavigationContext } from "./context/navigation.js";
 
 declare const __location: unique symbol;
 /**
@@ -24,6 +23,7 @@ declare const __location: unique symbol;
 export type AppLocation = string & {
   [__location]: true;
 };
+
 export type EmptyObject = Record<string, never>;
 
 export function urlPattern<
@@ -70,7 +70,7 @@ export function buildNullRoutDefinition<
  * @param path
  * @param params
  */
-function findMatch<T extends ObjectOf<RouteDefinition>>(
+export function findMatch<T extends ObjectOf<RouteDefinition>>(
   pagesMap: T,
   pageList: Array<keyof T>,
   path: string,
@@ -113,12 +113,12 @@ type RouteParamsType<
  */
 type MapKeyValue<Type> = {
   [Key in keyof Type]: Key extends string
-    ? {
-        parent: Type;
-        name: Key;
-        values: RouteParamsType<Type, Key>;
-      }
-    : never;
+  ? {
+    parent: Type;
+    name: Key;
+    values: RouteParamsType<Type, Key>;
+  }
+  : never;
 };
 
 /**
@@ -126,14 +126,4 @@ type MapKeyValue<Type> = {
  */
 type EnumerationOf<T> = T[keyof T];
 
-type Location<T> = EnumerationOf<MapKeyValue<T>>;
-
-// 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);
-}
+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]