gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 02/04: use request api from web-util


From: gnunet
Subject: [taler-wallet-core] 02/04: use request api from web-util
Date: Wed, 08 Feb 2023 21:41:35 +0100

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

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

commit 603efbd073a2a9aa56f801fe57d13f060821b05d
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Wed Feb 8 17:39:39 2023 -0300

    use request api from web-util
---
 .../merchant-backoffice-ui/src/InstanceRoutes.tsx  |  15 +-
 .../src/components/form/InputImage.tsx             |   2 +-
 packages/merchant-backoffice-ui/src/context/api.ts |  43 ----
 .../merchant-backoffice-ui/src/declaration.d.ts    |  15 +-
 .../merchant-backoffice-ui/src/hooks/backend.ts    | 108 ++++----
 .../merchant-backoffice-ui/src/hooks/instance.ts   |  34 ++-
 packages/merchant-backoffice-ui/src/hooks/order.ts |  34 ++-
 .../merchant-backoffice-ui/src/hooks/product.ts    |  22 +-
 .../merchant-backoffice-ui/src/hooks/reserves.ts   |  32 ++-
 .../merchant-backoffice-ui/src/hooks/templates.ts  |  37 ++-
 .../merchant-backoffice-ui/src/hooks/testing.tsx   |   9 +-
 .../merchant-backoffice-ui/src/hooks/transfer.ts   |  27 +-
 .../merchant-backoffice-ui/src/hooks/webhooks.ts   |  32 ++-
 .../src/paths/admin/list/index.tsx                 |   8 +-
 .../src/paths/instance/details/index.tsx           |   9 +-
 .../src/paths/instance/kyc/list/index.tsx          |   5 +-
 .../src/paths/instance/orders/create/index.tsx     |   5 +-
 .../src/paths/instance/orders/details/index.tsx    |   9 +-
 .../src/paths/instance/orders/list/index.tsx       |  10 +-
 .../src/paths/instance/products/list/index.tsx     |   8 +-
 .../src/paths/instance/products/update/index.tsx   |   8 +-
 .../paths/instance/reserves/create/CreatePage.tsx  |   3 +-
 .../src/paths/instance/reserves/details/index.tsx  |   5 +-
 .../src/paths/instance/reserves/list/index.tsx     |   8 +-
 .../src/paths/instance/templates/list/index.tsx    |   8 +-
 .../src/paths/instance/templates/update/index.tsx  |   8 +-
 .../paths/instance/templates/use/Use.stories.tsx   |   1 -
 .../src/paths/instance/templates/use/index.tsx     |   8 +-
 .../src/paths/instance/transfers/list/index.tsx    |   4 +-
 .../src/paths/instance/update/index.tsx            |  16 +-
 .../src/paths/instance/webhooks/list/index.tsx     |   8 +-
 .../src/paths/instance/webhooks/update/index.tsx   |   8 +-
 .../merchant-backoffice-ui/src/utils/request.ts    | 282 ---------------------
 33 files changed, 320 insertions(+), 511 deletions(-)

diff --git a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx 
b/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
index 56f223620..5929b031a 100644
--- a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
+++ b/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
@@ -19,7 +19,10 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  useTranslationContext,
+  HttpError,
+} from "@gnu-taler/web-util/lib/index.browser";
 import { format } from "date-fns";
 import { Fragment, FunctionComponent, h, VNode } from "preact";
 import { Route, route, Router } from "preact-router";
@@ -28,7 +31,6 @@ import { Loading } from "./components/exception/loading.js";
 import { Menu, NotificationCard } from "./components/menu/index.js";
 import { useBackendContext } from "./context/backend.js";
 import { InstanceContextProvider } from "./context/instance.js";
-import { HttpError } from "./utils/request.js";
 import {
   useBackendDefaultToken,
   useBackendInstanceToken,
@@ -63,6 +65,7 @@ import InstanceUpdatePage, {
 import LoginPage from "./paths/login/index.js";
 import NotFoundPage from "./paths/notfound/index.js";
 import { Notification } from "./utils/types.js";
+import { MerchantBackend } from "./declaration.js";
 
 export enum InstancePaths {
   // details = '/',
@@ -157,7 +160,9 @@ export function InstanceRoutes({
   );
 
   function ServerErrorRedirectTo(to: InstancePaths | AdminPaths) {
-    return function ServerErrorRedirectToImpl(error: HttpError) {
+    return function ServerErrorRedirectToImpl(
+      error: HttpError<MerchantBackend.ErrorDetail>,
+    ) {
       setGlobalNotification({
         message: i18n.str`The backend reported a problem: HTTP status 
#${error.status}`,
         description: i18n.str`Diagnostic from ${error.info?.url} is 
"${error.message}"`,
@@ -551,7 +556,7 @@ function AdminInstanceUpdatePage({
 }: { id: string } & InstanceUpdatePageProps): VNode {
   const [token, changeToken] = useBackendInstanceToken(id);
   const { updateLoginStatus: changeBackend } = useBackendContext();
-  const updateLoginStatus = (url: string, token?: string) => {
+  const updateLoginStatus = (url: string, token?: string): void => {
     changeBackend(url);
     if (token) changeToken(token);
   };
@@ -566,7 +571,7 @@ function AdminInstanceUpdatePage({
       <InstanceAdminUpdatePage
         {...rest}
         instanceId={id}
-        onLoadError={(error: HttpError) => {
+        onLoadError={(error: HttpError<MerchantBackend.ErrorDetail>) => {
           return (
             <Fragment>
               <NotificationCard
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx
index 43a7af1a3..4e4031c6a 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx
@@ -86,7 +86,7 @@ export function InputImage<T>({
                 }
                 setSizeError(false);
                 return f[0].arrayBuffer().then((b) => {
-                  const b64 = btoa(
+                  const b64 = window.btoa(
                     new Uint8Array(b).reduce(
                       (data, byte) => data + String.fromCharCode(byte),
                       "",
diff --git a/packages/merchant-backoffice-ui/src/context/api.ts 
b/packages/merchant-backoffice-ui/src/context/api.ts
deleted file mode 100644
index 81586bd35..000000000
--- a/packages/merchant-backoffice-ui/src/context/api.ts
+++ /dev/null
@@ -1,43 +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 { ComponentChildren, createContext, h, VNode } from "preact";
-import { useContext } from "preact/hooks";
-import { defaultRequestHandler } from "../utils/request.js";
-
-interface Type {
-  request: typeof defaultRequestHandler;
-}
-
-const Context = createContext<Type>({
-  request: defaultRequestHandler,
-});
-
-export const useApiContext = (): Type => useContext(Context);
-export const ApiContextProvider = ({
-  children,
-  value,
-}: {
-  value: Type;
-  children: ComponentChildren;
-}): VNode => {
-  return h(Context.Provider, { value, children });
-};
diff --git a/packages/merchant-backoffice-ui/src/declaration.d.ts 
b/packages/merchant-backoffice-ui/src/declaration.d.ts
index 32e6b44ea..e65835bfd 100644
--- a/packages/merchant-backoffice-ui/src/declaration.d.ts
+++ b/packages/merchant-backoffice-ui/src/declaration.d.ts
@@ -1355,14 +1355,13 @@ export namespace MerchantBackend {
 
     interface UsingTemplateResponse {
       // After enter the request. The user will be pay with a taler URL.
-      order_id: string,
-      token: string,
+      order_id: string;
+      token: string;
     }
   }
 
   namespace Webhooks {
     interface WebhookAddDetails {
-
       // Webhook ID to use.
       webhook_id: string;
 
@@ -1380,10 +1379,8 @@ export namespace MerchantBackend {
 
       // Body template by the webhook
       body_template?: string;
-
     }
     interface WebhookPatchDetails {
-
       // The event of the webhook: why the webhook is used.
       event_type: string;
 
@@ -1398,25 +1395,19 @@ export namespace MerchantBackend {
 
       // Body template by the webhook
       body_template?: string;
-
     }
     interface WebhookSummaryResponse {
-
       // List of webhooks that are present in our backend.
       webhooks: WebhookEntry[];
-
     }
     interface WebhookEntry {
-
       // Webhook identifier, as found in the webhook.
       webhook_id: string;
 
       // The event of the webhook: why the webhook is used.
       event_type: string;
-
     }
     interface WebhookDetails {
-
       // The event of the webhook: why the webhook is used.
       event_type: string;
 
@@ -1431,9 +1422,7 @@ export namespace MerchantBackend {
 
       // Body template by the webhook
       body_template?: string;
-
     }
-
   }
 
   interface ContractTerms {
diff --git a/packages/merchant-backoffice-ui/src/hooks/backend.ts 
b/packages/merchant-backoffice-ui/src/hooks/backend.ts
index 3f3db2fa1..952b33f7e 100644
--- a/packages/merchant-backoffice-ui/src/hooks/backend.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/backend.ts
@@ -28,8 +28,8 @@ import {
   HttpResponse,
   HttpResponseOk,
   RequestOptions,
-} from "../utils/request.js";
-import { useApiContext } from "../context/api.js";
+} from "@gnu-taler/web-util/lib/index.browser";
+import { useApiContext } from "@gnu-taler/web-util/lib/index.browser";
 
 export function useMatchMutate(): (
   re: RegExp,
@@ -54,12 +54,17 @@ export function useMatchMutate(): (
   };
 }
 
-export function useBackendInstancesTestForAdmin(): 
HttpResponse<MerchantBackend.Instances.InstancesResponse> {
+export function useBackendInstancesTestForAdmin(): HttpResponse<
+  MerchantBackend.Instances.InstancesResponse,
+  MerchantBackend.ErrorDetail
+> {
   const { request } = useBackendBaseRequest();
 
   type Type = MerchantBackend.Instances.InstancesResponse;
 
-  const [result, setResult] = useState<HttpResponse<Type>>({ loading: true });
+  const [result, setResult] = useState<
+    HttpResponse<Type, MerchantBackend.ErrorDetail>
+  >({ loading: true });
 
   useEffect(() => {
     request<Type>(`/management/instances`)
@@ -70,12 +75,17 @@ export function useBackendInstancesTestForAdmin(): 
HttpResponse<MerchantBackend.
   return result;
 }
 
-export function useBackendConfig(): 
HttpResponse<MerchantBackend.VersionResponse> {
+export function useBackendConfig(): HttpResponse<
+  MerchantBackend.VersionResponse,
+  MerchantBackend.ErrorDetail
+> {
   const { request } = useBackendBaseRequest();
 
   type Type = MerchantBackend.VersionResponse;
 
-  const [result, setResult] = useState<HttpResponse<Type>>({ loading: true });
+  const [result, setResult] = useState<
+    HttpResponse<Type, MerchantBackend.ErrorDetail>
+  >({ loading: true });
 
   useEffect(() => {
     request<Type>(`/config`)
@@ -88,15 +98,15 @@ export function useBackendConfig(): 
HttpResponse<MerchantBackend.VersionResponse
 
 interface useBackendInstanceRequestType {
   request: <T>(
-    path: string,
+    endpoint: string,
     options?: RequestOptions,
   ) => Promise<HttpResponseOk<T>>;
-  fetcher: <T>(path: string) => Promise<HttpResponseOk<T>>;
-  reserveDetailFetcher: <T>(path: string) => Promise<HttpResponseOk<T>>;
-  tipsDetailFetcher: <T>(path: string) => Promise<HttpResponseOk<T>>;
+  fetcher: <T>(endpoint: string) => Promise<HttpResponseOk<T>>;
+  reserveDetailFetcher: <T>(endpoint: string) => Promise<HttpResponseOk<T>>;
+  tipsDetailFetcher: <T>(endpoint: string) => Promise<HttpResponseOk<T>>;
   multiFetcher: <T>(url: string[]) => Promise<HttpResponseOk<T>[]>;
   orderFetcher: <T>(
-    path: string,
+    endpoint: string,
     paid?: YesOrNo,
     refunded?: YesOrNo,
     wired?: YesOrNo,
@@ -104,26 +114,26 @@ interface useBackendInstanceRequestType {
     delta?: number,
   ) => Promise<HttpResponseOk<T>>;
   transferFetcher: <T>(
-    path: string,
+    endpoint: string,
     payto_uri?: string,
     verified?: string,
     position?: string,
     delta?: number,
   ) => Promise<HttpResponseOk<T>>;
   templateFetcher: <T>(
-    path: string,
+    endpoint: string,
     position?: string,
     delta?: number,
   ) => Promise<HttpResponseOk<T>>;
   webhookFetcher: <T>(
-    path: string,
+    endpoint: string,
     position?: string,
     delta?: number,
   ) => Promise<HttpResponseOk<T>>;
 }
 interface useBackendBaseRequestType {
   request: <T>(
-    path: string,
+    endpoint: string,
     options?: RequestOptions,
   ) => Promise<HttpResponseOk<T>>;
 }
@@ -141,10 +151,10 @@ export function useBackendBaseRequest(): 
useBackendBaseRequestType {
 
   const request = useCallback(
     function requestImpl<T>(
-      path: string,
+      endpoint: string,
       options: RequestOptions = {},
     ): Promise<HttpResponseOk<T>> {
-      return requestHandler<T>(backend, path, { token, ...options });
+      return requestHandler<T>(backend, endpoint, { token, ...options });
     },
     [backend, token],
   );
@@ -153,45 +163,47 @@ export function useBackendBaseRequest(): 
useBackendBaseRequestType {
 }
 
 export function useBackendInstanceRequest(): useBackendInstanceRequestType {
-  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { url: rootBackendUrl, token: rootToken } = useBackendContext();
   const { token: instanceToken, id, admin } = useInstanceContext();
   const { request: requestHandler } = useApiContext();
 
-  const { backend, token } = !admin
-    ? { backend: baseUrl, token: baseToken }
-    : { backend: `${baseUrl}/instances/${id}`, token: instanceToken };
+  const { baseUrl, token } = !admin
+    ? { baseUrl: rootBackendUrl, token: rootToken }
+    : { baseUrl: `${rootBackendUrl}/instances/${id}`, token: instanceToken };
 
   const request = useCallback(
     function requestImpl<T>(
-      path: string,
+      endpoint: string,
       options: RequestOptions = {},
     ): Promise<HttpResponseOk<T>> {
-      return requestHandler<T>(backend, path, { token, ...options });
+      return requestHandler<T>(baseUrl, endpoint, { token, ...options });
     },
-    [backend, token],
+    [baseUrl, token],
   );
 
   const multiFetcher = useCallback(
     function multiFetcherImpl<T>(
-      paths: string[],
+      endpoints: string[],
     ): Promise<HttpResponseOk<T>[]> {
       return Promise.all(
-        paths.map((path) => requestHandler<T>(backend, path, { token })),
+        endpoints.map((endpoint) =>
+          requestHandler<T>(baseUrl, endpoint, { token }),
+        ),
       );
     },
-    [backend, token],
+    [baseUrl, token],
   );
 
   const fetcher = useCallback(
-    function fetcherImpl<T>(path: string): Promise<HttpResponseOk<T>> {
-      return requestHandler<T>(backend, path, { token });
+    function fetcherImpl<T>(endpoint: string): Promise<HttpResponseOk<T>> {
+      return requestHandler<T>(baseUrl, endpoint, { token });
     },
-    [backend, token],
+    [baseUrl, token],
   );
 
   const orderFetcher = useCallback(
     function orderFetcherImpl<T>(
-      path: string,
+      endpoint: string,
       paid?: YesOrNo,
       refunded?: YesOrNo,
       wired?: YesOrNo,
@@ -208,42 +220,42 @@ export function useBackendInstanceRequest(): 
useBackendInstanceRequestType {
       if (refunded !== undefined) params.refunded = refunded;
       if (wired !== undefined) params.wired = wired;
       if (date_ms !== undefined) params.date_ms = date_ms;
-      return requestHandler<T>(backend, path, { params, token });
+      return requestHandler<T>(baseUrl, endpoint, { params, token });
     },
-    [backend, token],
+    [baseUrl, token],
   );
 
   const reserveDetailFetcher = useCallback(
     function reserveDetailFetcherImpl<T>(
-      path: string,
+      endpoint: string,
     ): Promise<HttpResponseOk<T>> {
-      return requestHandler<T>(backend, path, {
+      return requestHandler<T>(baseUrl, endpoint, {
         params: {
           tips: "yes",
         },
         token,
       });
     },
-    [backend, token],
+    [baseUrl, token],
   );
 
   const tipsDetailFetcher = useCallback(
     function tipsDetailFetcherImpl<T>(
-      path: string,
+      endpoint: string,
     ): Promise<HttpResponseOk<T>> {
-      return requestHandler<T>(backend, path, {
+      return requestHandler<T>(baseUrl, endpoint, {
         params: {
           pickups: "yes",
         },
         token,
       });
     },
-    [backend, token],
+    [baseUrl, token],
   );
 
   const transferFetcher = useCallback(
     function transferFetcherImpl<T>(
-      path: string,
+      endpoint: string,
       payto_uri?: string,
       verified?: string,
       position?: string,
@@ -257,14 +269,14 @@ export function useBackendInstanceRequest(): 
useBackendInstanceRequestType {
       }
       if (position !== undefined) params.offset = position;
 
-      return requestHandler<T>(backend, path, { params, token });
+      return requestHandler<T>(baseUrl, endpoint, { params, token });
     },
-    [backend, token],
+    [baseUrl, token],
   );
 
   const templateFetcher = useCallback(
     function templateFetcherImpl<T>(
-      path: string,
+      endpoint: string,
       position?: string,
       delta?: number,
     ): Promise<HttpResponseOk<T>> {
@@ -274,14 +286,14 @@ export function useBackendInstanceRequest(): 
useBackendInstanceRequestType {
       }
       if (position !== undefined) params.offset = position;
 
-      return requestHandler<T>(backend, path, { params, token });
+      return requestHandler<T>(baseUrl, endpoint, { params, token });
     },
-    [backend, token],
+    [baseUrl, token],
   );
 
   const webhookFetcher = useCallback(
     function webhookFetcherImpl<T>(
-      path: string,
+      endpoint: string,
       position?: string,
       delta?: number,
     ): Promise<HttpResponseOk<T>> {
@@ -291,9 +303,9 @@ export function useBackendInstanceRequest(): 
useBackendInstanceRequestType {
       }
       if (position !== undefined) params.offset = position;
 
-      return requestHandler<T>(backend, path, { params, token });
+      return requestHandler<T>(baseUrl, endpoint, { params, token });
     },
-    [backend, token],
+    [baseUrl, token],
   );
 
   return {
diff --git a/packages/merchant-backoffice-ui/src/hooks/instance.ts 
b/packages/merchant-backoffice-ui/src/hooks/instance.ts
index 3c05472d0..f118e1e6e 100644
--- a/packages/merchant-backoffice-ui/src/hooks/instance.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/instance.ts
@@ -16,7 +16,11 @@
 import useSWR, { useSWRConfig } from "swr";
 import { useBackendContext } from "../context/backend.js";
 import { MerchantBackend } from "../declaration.js";
-import { HttpError, HttpResponse, HttpResponseOk } from "../utils/request.js";
+import {
+  HttpError,
+  HttpResponse,
+  HttpResponseOk,
+} from "@gnu-taler/web-util/lib/index.browser";
 import {
   useBackendBaseRequest,
   useBackendInstanceRequest,
@@ -176,12 +180,15 @@ export function useInstanceAPI(): InstanceAPI {
   return { updateInstance, deleteInstance, setNewToken, clearToken };
 }
 
-export function useInstanceDetails(): 
HttpResponse<MerchantBackend.Instances.QueryInstancesResponse> {
+export function useInstanceDetails(): HttpResponse<
+  MerchantBackend.Instances.QueryInstancesResponse,
+  MerchantBackend.ErrorDetail
+> {
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
     HttpResponseOk<MerchantBackend.Instances.QueryInstancesResponse>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/private/`], fetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
@@ -203,12 +210,15 @@ type KYCStatus =
   | { type: "ok" }
   | { type: "redirect"; status: MerchantBackend.Instances.AccountKycRedirects 
};
 
-export function useInstanceKYCDetails(): HttpResponse<KYCStatus> {
+export function useInstanceKYCDetails(): HttpResponse<
+  KYCStatus,
+  MerchantBackend.ErrorDetail
+> {
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error } = useSWR<
     HttpResponseOk<MerchantBackend.Instances.AccountKycRedirects>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/private/kyc`], fetcher, {
     refreshInterval: 5000,
     refreshWhenHidden: false,
@@ -231,12 +241,15 @@ export function useInstanceKYCDetails(): 
HttpResponse<KYCStatus> {
 
 export function useManagedInstanceDetails(
   instanceId: string,
-): HttpResponse<MerchantBackend.Instances.QueryInstancesResponse> {
+): HttpResponse<
+  MerchantBackend.Instances.QueryInstancesResponse,
+  MerchantBackend.ErrorDetail
+> {
   const { request } = useBackendBaseRequest();
 
   const { data, error, isValidating } = useSWR<
     HttpResponseOk<MerchantBackend.Instances.QueryInstancesResponse>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/management/instances/${instanceId}`], request, {
     refreshInterval: 0,
     refreshWhenHidden: false,
@@ -254,12 +267,15 @@ export function useManagedInstanceDetails(
   return { loading: true };
 }
 
-export function useBackendInstances(): 
HttpResponse<MerchantBackend.Instances.InstancesResponse> {
+export function useBackendInstances(): HttpResponse<
+  MerchantBackend.Instances.InstancesResponse,
+  MerchantBackend.ErrorDetail
+> {
   const { request } = useBackendBaseRequest();
 
   const { data, error, isValidating } = useSWR<
     HttpResponseOk<MerchantBackend.Instances.InstancesResponse>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >(["/management/instances"], request);
 
   if (isValidating) return { loading: true, data: data?.data };
diff --git a/packages/merchant-backoffice-ui/src/hooks/order.ts 
b/packages/merchant-backoffice-ui/src/hooks/order.ts
index 5be480160..c01f8dd83 100644
--- a/packages/merchant-backoffice-ui/src/hooks/order.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/order.ts
@@ -22,7 +22,7 @@ import {
   HttpResponse,
   HttpResponseOk,
   HttpResponsePaginated,
-} from "../utils/request.js";
+} from "@gnu-taler/web-util/lib/index.browser";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 export interface OrderAPI {
@@ -128,12 +128,15 @@ export function useOrderAPI(): OrderAPI {
 
 export function useOrderDetails(
   oderId: string,
-): HttpResponse<MerchantBackend.Orders.MerchantOrderStatusResponse> {
+): HttpResponse<
+  MerchantBackend.Orders.MerchantOrderStatusResponse,
+  MerchantBackend.ErrorDetail
+> {
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
     HttpResponseOk<MerchantBackend.Orders.MerchantOrderStatusResponse>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/private/orders/${oderId}`], fetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
@@ -158,7 +161,10 @@ export interface InstanceOrderFilter {
 export function useInstanceOrders(
   args?: InstanceOrderFilter,
   updateFilter?: (d: Date) => void,
-): HttpResponsePaginated<MerchantBackend.Orders.OrderHistory> {
+): HttpResponsePaginated<
+  MerchantBackend.Orders.OrderHistory,
+  MerchantBackend.ErrorDetail
+> {
   const { orderFetcher } = useBackendInstanceRequest();
 
   const [pageBefore, setPageBefore] = useState(1);
@@ -177,7 +183,10 @@ export function useInstanceOrders(
     data: beforeData,
     error: beforeError,
     isValidating: loadingBefore,
-  } = useSWR<HttpResponseOk<MerchantBackend.Orders.OrderHistory>, HttpError>(
+  } = useSWR<
+    HttpResponseOk<MerchantBackend.Orders.OrderHistory>,
+    HttpError<MerchantBackend.ErrorDetail>
+  >(
     [
       `/private/orders`,
       args?.paid,
@@ -192,7 +201,10 @@ export function useInstanceOrders(
     data: afterData,
     error: afterError,
     isValidating: loadingAfter,
-  } = useSWR<HttpResponseOk<MerchantBackend.Orders.OrderHistory>, HttpError>(
+  } = useSWR<
+    HttpResponseOk<MerchantBackend.Orders.OrderHistory>,
+    HttpError<MerchantBackend.ErrorDetail>
+  >(
     [
       `/private/orders`,
       args?.paid,
@@ -206,10 +218,16 @@ export function useInstanceOrders(
 
   //this will save last result
   const [lastBefore, setLastBefore] = useState<
-    HttpResponse<MerchantBackend.Orders.OrderHistory>
+    HttpResponse<
+      MerchantBackend.Orders.OrderHistory,
+      MerchantBackend.ErrorDetail
+    >
   >({ loading: true });
   const [lastAfter, setLastAfter] = useState<
-    HttpResponse<MerchantBackend.Orders.OrderHistory>
+    HttpResponse<
+      MerchantBackend.Orders.OrderHistory,
+      MerchantBackend.ErrorDetail
+    >
   >({ loading: true });
   useEffect(() => {
     if (afterData) setLastAfter(afterData);
diff --git a/packages/merchant-backoffice-ui/src/hooks/product.ts 
b/packages/merchant-backoffice-ui/src/hooks/product.ts
index af8ad74f3..5d95a2f8f 100644
--- a/packages/merchant-backoffice-ui/src/hooks/product.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/product.ts
@@ -15,7 +15,11 @@
  */
 import useSWR, { useSWRConfig } from "swr";
 import { MerchantBackend, WithId } from "../declaration.js";
-import { HttpError, HttpResponse, HttpResponseOk } from "../utils/request.js";
+import {
+  HttpError,
+  HttpResponse,
+  HttpResponseOk,
+} from "@gnu-taler/web-util/lib/index.browser";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 export interface ProductAPI {
@@ -85,13 +89,14 @@ export function useProductAPI(): ProductAPI {
 }
 
 export function useInstanceProducts(): HttpResponse<
-  (MerchantBackend.Products.ProductDetail & WithId)[]
+  (MerchantBackend.Products.ProductDetail & WithId)[],
+  MerchantBackend.ErrorDetail
 > {
   const { fetcher, multiFetcher } = useBackendInstanceRequest();
 
   const { data: list, error: listError } = useSWR<
     HttpResponseOk<MerchantBackend.Products.InventorySummaryResponse>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/private/products`], fetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
@@ -105,7 +110,7 @@ export function useInstanceProducts(): HttpResponse<
   );
   const { data: products, error: productError } = useSWR<
     HttpResponseOk<MerchantBackend.Products.ProductDetail>[],
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([paths], multiFetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
@@ -122,7 +127,7 @@ export function useInstanceProducts(): HttpResponse<
       //take the id from the queried url
       return {
         ...d.data,
-        id: d.info?.url.href.replace(/.*\/private\/products\//, "") || "",
+        id: d.info?.url.replace(/.*\/private\/products\//, "") || "",
       };
     });
     return { ok: true, data: dataWithId };
@@ -132,12 +137,15 @@ export function useInstanceProducts(): HttpResponse<
 
 export function useProductDetails(
   productId: string,
-): HttpResponse<MerchantBackend.Products.ProductDetail> {
+): HttpResponse<
+  MerchantBackend.Products.ProductDetail,
+  MerchantBackend.ErrorDetail
+> {
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
     HttpResponseOk<MerchantBackend.Products.ProductDetail>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/private/products/${productId}`], fetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
diff --git a/packages/merchant-backoffice-ui/src/hooks/reserves.ts 
b/packages/merchant-backoffice-ui/src/hooks/reserves.ts
index dc127af13..0215f32c5 100644
--- a/packages/merchant-backoffice-ui/src/hooks/reserves.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/reserves.ts
@@ -15,7 +15,11 @@
  */
 import useSWR, { useSWRConfig } from "swr";
 import { MerchantBackend } from "../declaration.js";
-import { HttpError, HttpResponse, HttpResponseOk } from "../utils/request.js";
+import {
+  HttpError,
+  HttpResponse,
+  HttpResponseOk,
+} from "@gnu-taler/web-util/lib/index.browser";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 export function useReservesAPI(): ReserveMutateAPI {
@@ -77,7 +81,9 @@ export function useReservesAPI(): ReserveMutateAPI {
     return res;
   };
 
-  const deleteReserve = async (pub: string): Promise<HttpResponse<void>> => {
+  const deleteReserve = async (
+    pub: string,
+  ): Promise<HttpResponse<void, MerchantBackend.ErrorDetail>> => {
     const res = await request<void>(`/private/reserves/${pub}`, {
       method: "DELETE",
     });
@@ -102,15 +108,20 @@ export interface ReserveMutateAPI {
   authorizeTip: (
     data: MerchantBackend.Tips.TipCreateRequest,
   ) => Promise<HttpResponseOk<MerchantBackend.Tips.TipCreateConfirmation>>;
-  deleteReserve: (id: string) => Promise<HttpResponse<void>>;
+  deleteReserve: (
+    id: string,
+  ) => Promise<HttpResponse<void, MerchantBackend.ErrorDetail>>;
 }
 
-export function useInstanceReserves(): 
HttpResponse<MerchantBackend.Tips.TippingReserveStatus> {
+export function useInstanceReserves(): HttpResponse<
+  MerchantBackend.Tips.TippingReserveStatus,
+  MerchantBackend.ErrorDetail
+> {
   const { fetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
     HttpResponseOk<MerchantBackend.Tips.TippingReserveStatus>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/private/reserves`], fetcher);
 
   if (isValidating) return { loading: true, data: data?.data };
@@ -121,12 +132,15 @@ export function useInstanceReserves(): 
HttpResponse<MerchantBackend.Tips.Tipping
 
 export function useReserveDetails(
   reserveId: string,
-): HttpResponse<MerchantBackend.Tips.ReserveDetail> {
+): HttpResponse<
+  MerchantBackend.Tips.ReserveDetail,
+  MerchantBackend.ErrorDetail
+> {
   const { reserveDetailFetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
     HttpResponseOk<MerchantBackend.Tips.ReserveDetail>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/private/reserves/${reserveId}`], reserveDetailFetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
@@ -143,12 +157,12 @@ export function useReserveDetails(
 
 export function useTipDetails(
   tipId: string,
-): HttpResponse<MerchantBackend.Tips.TipDetails> {
+): HttpResponse<MerchantBackend.Tips.TipDetails, MerchantBackend.ErrorDetail> {
   const { tipsDetailFetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
     HttpResponseOk<MerchantBackend.Tips.TipDetails>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/private/tips/${tipId}`], tipsDetailFetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
diff --git a/packages/merchant-backoffice-ui/src/hooks/templates.ts 
b/packages/merchant-backoffice-ui/src/hooks/templates.ts
index 3a28b903d..124786887 100644
--- a/packages/merchant-backoffice-ui/src/hooks/templates.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/templates.ts
@@ -23,7 +23,7 @@ import {
   HttpResponse,
   HttpResponseOk,
   HttpResponsePaginated,
-} from "../utils/request.js";
+} from "@gnu-taler/web-util/lib/index.browser";
 
 export function useTemplateAPI(): TemplateAPI {
   const mutateAll = useMatchMutate();
@@ -79,7 +79,12 @@ export function useTemplateAPI(): TemplateAPI {
     return res;
   };
 
-  return { createTemplate, updateTemplate, deleteTemplate, 
createOrderFromTemplate };
+  return {
+    createTemplate,
+    updateTemplate,
+    deleteTemplate,
+    createOrderFromTemplate,
+  };
 }
 
 export interface TemplateAPI {
@@ -105,7 +110,10 @@ export interface InstanceTemplateFilter {
 export function useInstanceTemplates(
   args?: InstanceTemplateFilter,
   updatePosition?: (id: string) => void,
-): HttpResponsePaginated<MerchantBackend.Template.TemplateSummaryResponse> {
+): HttpResponsePaginated<
+  MerchantBackend.Template.TemplateSummaryResponse,
+  MerchantBackend.ErrorDetail
+> {
   const { templateFetcher } = useBackendInstanceRequest();
 
   // const [pageBefore, setPageBefore] = useState(1);
@@ -140,15 +148,18 @@ export function useInstanceTemplates(
     isValidating: loadingAfter,
   } = useSWR<
     HttpResponseOk<MerchantBackend.Template.TemplateSummaryResponse>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/private/templates`, args?.position, -totalAfter], templateFetcher);
 
   //this will save last result
   // const [lastBefore, setLastBefore] = useState<
-  //   HttpResponse<MerchantBackend.Template.TemplateSummaryResponse>
+  //   HttpResponse<MerchantBackend.Template.TemplateSummaryResponse, 
MerchantBackend.ErrorDetail>
   // >({ loading: true });
   const [lastAfter, setLastAfter] = useState<
-    HttpResponse<MerchantBackend.Template.TemplateSummaryResponse>
+    HttpResponse<
+      MerchantBackend.Template.TemplateSummaryResponse,
+      MerchantBackend.ErrorDetail
+    >
   >({ loading: true });
   useEffect(() => {
     if (afterData) setLastAfter(afterData);
@@ -174,9 +185,10 @@ export function useInstanceTemplates(
       if (afterData.data.templates.length < MAX_RESULT_SIZE) {
         setPageAfter(pageAfter + 1);
       } else {
-        const from = 
`${afterData.data.templates[afterData.data.templates.length - 1]
-          .template_id
-          }`;
+        const from = `${
+          afterData.data.templates[afterData.data.templates.length - 1]
+            .template_id
+        }`;
         if (from && updatePosition) updatePosition(from);
       }
     },
@@ -211,12 +223,15 @@ export function useInstanceTemplates(
 
 export function useTemplateDetails(
   templateId: string,
-): HttpResponse<MerchantBackend.Template.TemplateDetails> {
+): HttpResponse<
+  MerchantBackend.Template.TemplateDetails,
+  MerchantBackend.ErrorDetail
+> {
   const { templateFetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
     HttpResponseOk<MerchantBackend.Template.TemplateDetails>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/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 8c5a5a36b..64e646bb5 100644
--- a/packages/merchant-backoffice-ui/src/hooks/testing.tsx
+++ b/packages/merchant-backoffice-ui/src/hooks/testing.tsx
@@ -22,10 +22,13 @@
 import { MockEnvironment } from "@gnu-taler/web-util/lib/tests/mock";
 import { ComponentChildren, FunctionalComponent, h, VNode } from "preact";
 import { SWRConfig } from "swr";
-import { ApiContextProvider } from "../context/api.js";
+import { ApiContextProvider } from "@gnu-taler/web-util/lib/index.browser";
 import { BackendContextProvider } from "../context/backend.js";
 import { InstanceContextProvider } from "../context/instance.js";
-import { HttpResponseOk, RequestOptions } from "../utils/request.js";
+import {
+  HttpResponseOk,
+  RequestOptions,
+} from "@gnu-taler/web-util/lib/index.browser";
 
 export class ApiMockEnvironment extends MockEnvironment {
   constructor(debug = false) {
@@ -78,7 +81,7 @@ export class ApiMockEnvironment extends MockEnvironment {
           info: {
             hasToken: !!options.token,
             status: !mocked ? 200 : mocked.status,
-            url: _url,
+            url: _url.href,
             payload: options.data,
           },
         };
diff --git a/packages/merchant-backoffice-ui/src/hooks/transfer.ts 
b/packages/merchant-backoffice-ui/src/hooks/transfer.ts
index b86247476..6b30047e9 100644
--- a/packages/merchant-backoffice-ui/src/hooks/transfer.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/transfer.ts
@@ -22,7 +22,7 @@ import {
   HttpResponse,
   HttpResponseOk,
   HttpResponsePaginated,
-} from "../utils/request.js";
+} from "@gnu-taler/web-util/lib/index.browser";
 import { useBackendInstanceRequest, useMatchMutate } from "./backend.js";
 
 export function useTransferAPI(): TransferAPI {
@@ -67,7 +67,10 @@ export interface InstanceTransferFilter {
 export function useInstanceTransfers(
   args?: InstanceTransferFilter,
   updatePosition?: (id: string) => void,
-): HttpResponsePaginated<MerchantBackend.Transfers.TransferList> {
+): HttpResponsePaginated<
+  MerchantBackend.Transfers.TransferList,
+  MerchantBackend.ErrorDetail
+> {
   const { transferFetcher } = useBackendInstanceRequest();
 
   const [pageBefore, setPageBefore] = useState(1);
@@ -86,7 +89,10 @@ export function useInstanceTransfers(
     data: beforeData,
     error: beforeError,
     isValidating: loadingBefore,
-  } = useSWR<HttpResponseOk<MerchantBackend.Transfers.TransferList>, 
HttpError>(
+  } = useSWR<
+    HttpResponseOk<MerchantBackend.Transfers.TransferList>,
+    HttpError<MerchantBackend.ErrorDetail>
+  >(
     [
       `/private/transfers`,
       args?.payto_uri,
@@ -100,7 +106,10 @@ export function useInstanceTransfers(
     data: afterData,
     error: afterError,
     isValidating: loadingAfter,
-  } = useSWR<HttpResponseOk<MerchantBackend.Transfers.TransferList>, 
HttpError>(
+  } = useSWR<
+    HttpResponseOk<MerchantBackend.Transfers.TransferList>,
+    HttpError<MerchantBackend.ErrorDetail>
+  >(
     [
       `/private/transfers`,
       args?.payto_uri,
@@ -113,10 +122,16 @@ export function useInstanceTransfers(
 
   //this will save last result
   const [lastBefore, setLastBefore] = useState<
-    HttpResponse<MerchantBackend.Transfers.TransferList>
+    HttpResponse<
+      MerchantBackend.Transfers.TransferList,
+      MerchantBackend.ErrorDetail
+    >
   >({ loading: true });
   const [lastAfter, setLastAfter] = useState<
-    HttpResponse<MerchantBackend.Transfers.TransferList>
+    HttpResponse<
+      MerchantBackend.Transfers.TransferList,
+      MerchantBackend.ErrorDetail
+    >
   >({ loading: true });
   useEffect(() => {
     if (afterData) setLastAfter(afterData);
diff --git a/packages/merchant-backoffice-ui/src/hooks/webhooks.ts 
b/packages/merchant-backoffice-ui/src/hooks/webhooks.ts
index 9f196cefa..e1cd3daf2 100644
--- a/packages/merchant-backoffice-ui/src/hooks/webhooks.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/webhooks.ts
@@ -23,7 +23,7 @@ import {
   HttpResponse,
   HttpResponseOk,
   HttpResponsePaginated,
-} from "../utils/request.js";
+} from "@gnu-taler/web-util/lib/index.browser";
 
 export function useWebhookAPI(): WebhookAPI {
   const mutateAll = useMatchMutate();
@@ -84,7 +84,10 @@ export interface InstanceWebhookFilter {
 export function useInstanceWebhooks(
   args?: InstanceWebhookFilter,
   updatePosition?: (id: string) => void,
-): HttpResponsePaginated<MerchantBackend.Webhooks.WebhookSummaryResponse> {
+): HttpResponsePaginated<
+  MerchantBackend.Webhooks.WebhookSummaryResponse,
+  MerchantBackend.ErrorDetail
+> {
   const { webhookFetcher } = useBackendInstanceRequest();
 
   const [pageAfter, setPageAfter] = useState(1);
@@ -97,11 +100,14 @@ export function useInstanceWebhooks(
     isValidating: loadingAfter,
   } = useSWR<
     HttpResponseOk<MerchantBackend.Webhooks.WebhookSummaryResponse>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/private/webhooks`, args?.position, -totalAfter], webhookFetcher);
 
   const [lastAfter, setLastAfter] = useState<
-    HttpResponse<MerchantBackend.Webhooks.WebhookSummaryResponse>
+    HttpResponse<
+      MerchantBackend.Webhooks.WebhookSummaryResponse,
+      MerchantBackend.ErrorDetail
+    >
   >({ loading: true });
   useEffect(() => {
     if (afterData) setLastAfter(afterData);
@@ -121,21 +127,20 @@ export function useInstanceWebhooks(
       if (afterData.data.webhooks.length < MAX_RESULT_SIZE) {
         setPageAfter(pageAfter + 1);
       } else {
-        const from = `${afterData.data.webhooks[afterData.data.webhooks.length 
- 1]
-          .webhook_id
-          }`;
+        const from = `${
+          afterData.data.webhooks[afterData.data.webhooks.length - 
1].webhook_id
+        }`;
         if (from && updatePosition) updatePosition(from);
       }
     },
     loadMorePrev: () => {
-      return
+      return;
     },
   };
 
   const webhooks = !afterData ? [] : (afterData || lastAfter).data.webhooks;
 
-  if (loadingAfter)
-    return { loading: true, data: { webhooks } };
+  if (loadingAfter) return { loading: true, data: { webhooks } };
   if (afterData) {
     return { ok: true, data: { webhooks }, ...pagination };
   }
@@ -144,12 +149,15 @@ export function useInstanceWebhooks(
 
 export function useWebhookDetails(
   webhookId: string,
-): HttpResponse<MerchantBackend.Webhooks.WebhookDetails> {
+): HttpResponse<
+  MerchantBackend.Webhooks.WebhookDetails,
+  MerchantBackend.ErrorDetail
+> {
   const { webhookFetcher } = useBackendInstanceRequest();
 
   const { data, error, isValidating } = useSWR<
     HttpResponseOk<MerchantBackend.Webhooks.WebhookDetails>,
-    HttpError
+    HttpError<MerchantBackend.ErrorDetail>
   >([`/private/webhooks/${webhookId}`], webhookFetcher, {
     refreshInterval: 0,
     refreshWhenHidden: false,
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 bac7a39eb..8efb5598d 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx
@@ -19,14 +19,16 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  HttpError,
+  useTranslationContext,
+} from "@gnu-taler/web-util/lib/index.browser";
 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 { DeleteModal, PurgeModal } from "../../../components/modal/index.js";
 import { MerchantBackend } from "../../../declaration.js";
-import { HttpError } from "../../../utils/request.js";
 import { useAdminAPI, useBackendInstances } from "../../../hooks/instance.js";
 import { Notification } from "../../../utils/types.js";
 import { View } from "./View.js";
@@ -37,7 +39,7 @@ interface Props {
   instances: MerchantBackend.Instances.Instance[];
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (error: HttpError) => VNode;
+  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   setInstanceName: (s: string) => void;
 }
 
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 56d5c0755..8f7d9b136 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/details/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/details/index.tsx
@@ -13,18 +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 { HttpError } from "@gnu-taler/web-util/lib/index.browser.js";
 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 { HttpError } from "../../../utils/request.js";
+import { MerchantBackend } from "../../../declaration.js";
 import { useInstanceAPI, useInstanceDetails } from 
"../../../hooks/instance.js";
 import { DetailPage } from "./DetailPage.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError) => VNode;
+  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   onUpdate: () => void;
   onNotFound: () => VNode;
   onDelete: () => void;
@@ -63,7 +64,9 @@ export default function Detail({
             try {
               await deleteInstance();
               onDelete();
-            } catch (error) {}
+            } catch (error) {
+              //FIXME: show message error
+            }
             setDeleting(false);
           }}
         />
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 83af002b3..dba2aab21 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
@@ -19,15 +19,16 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpError } from "@gnu-taler/web-util/lib/index.browser.js";
 import { h, VNode } from "preact";
 import { Loading } from "../../../../components/exception/loading.js";
-import { HttpError } from "../../../../utils/request.js";
+import { MerchantBackend } from "../../../../declaration.js";
 import { useInstanceKYCDetails } from "../../../../hooks/instance.js";
 import { ListPage } from "./ListPage.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError) => VNode;
+  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   onNotFound: () => VNode;
 }
 
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 5c6293a81..a37df2176 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
@@ -19,18 +19,17 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpError } from "@gnu-taler/web-util/lib/index.browser.js";
 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 { HttpError } from "../../../../utils/request.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 { OrderCreatedSuccessfully } from "./OrderCreatedSuccessfully.js";
 
 export type Entity = {
   request: MerchantBackend.Orders.PostOrderRequest;
@@ -41,7 +40,7 @@ interface Props {
   onConfirm: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (error: HttpError) => VNode;
+  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
 }
 export default function OrderCreate({
   onConfirm,
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 19aaddf50..986c46b95 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
@@ -13,12 +13,15 @@
  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 { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  useTranslationContext,
+  HttpError,
+} from "@gnu-taler/web-util/lib/index.browser";
 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 { HttpError } from "../../../../utils/request.js";
+import { MerchantBackend } from "../../../../declaration.js";
 import { useOrderAPI, useOrderDetails } from "../../../../hooks/order.js";
 import { Notification } from "../../../../utils/types.js";
 import { DetailPage } from "./DetailPage.js";
@@ -29,7 +32,7 @@ export interface Props {
   onBack: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (error: HttpError) => VNode;
+  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
 }
 
 export default function Update({
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 3744ce8c5..bd0924808 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
@@ -19,13 +19,15 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  HttpError,
+  useTranslationContext,
+} from "@gnu-taler/web-util/lib/index.browser";
 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 { HttpError } from "../../../../utils/request.js";
 import {
   InstanceOrderFilter,
   useInstanceOrders,
@@ -38,7 +40,7 @@ import { RefundModal } from "./Table.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError) => VNode;
+  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onSelect: (id: string) => void;
   onCreate: () => void;
@@ -177,7 +179,7 @@ export default function OrderList({
 interface RefundProps {
   id: string;
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError) => VNode;
+  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onCancel: () => void;
   onConfirm: (m: MerchantBackend.Orders.RefundRequest) => void;
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 25332acee..c32339563 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
@@ -19,13 +19,15 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  HttpError,
+  useTranslationContext,
+} from "@gnu-taler/web-util/lib/index.browser";
 import { 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 { HttpError } from "../../../../utils/request.js";
 import {
   useInstanceProducts,
   useProductAPI,
@@ -38,7 +40,7 @@ interface Props {
   onNotFound: () => VNode;
   onCreate: () => void;
   onSelect: (id: string) => void;
-  onLoadError: (e: HttpError) => VNode;
+  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
 }
 export default function ProductList({
   onUnauthorized,
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 5b19a7aa3..b35606f53 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
@@ -19,13 +19,15 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  HttpError,
+  useTranslationContext,
+} from "@gnu-taler/web-util/lib/index.browser";
 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 { HttpError } from "../../../../utils/request.js";
 import { useProductAPI, useProductDetails } from 
"../../../../hooks/product.js";
 import { Notification } from "../../../../utils/types.js";
 import { UpdatePage } from "./UpdatePage.js";
@@ -36,7 +38,7 @@ interface Props {
   onConfirm: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError) => VNode;
+  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   pid: string;
 }
 export default function UpdateProduct({
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
index eeb59611c..c0c36e651 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
@@ -30,8 +30,7 @@ import {
 import { Input } from "../../../../components/form/Input.js";
 import { InputCurrency } from "../../../../components/form/InputCurrency.js";
 import { InputSelector } from "../../../../components/form/InputSelector.js";
-import { ExchangeBackend, MerchantBackend } from "../../../../declaration.js";
-// import { request } from "../../../../utils/request.js";
+import { MerchantBackend } from "../../../../declaration.js";
 import {
   PAYTO_WIRE_METHOD_LOOKUP,
   URL_REGEX,
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/index.tsx
index 57ee566d1..e7ec68fab 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/index.tsx
@@ -19,9 +19,10 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpError } from "@gnu-taler/web-util/lib/index.browser.js";
 import { Fragment, h, VNode } from "preact";
 import { Loading } from "../../../../components/exception/loading.js";
-import { HttpError } from "../../../../utils/request.js";
+import { MerchantBackend } from "../../../../declaration.js";
 import { useReserveDetails } from "../../../../hooks/reserves.js";
 import { DetailPage } from "./DetailPage.js";
 
@@ -29,7 +30,7 @@ interface Props {
   rid: string;
 
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError) => VNode;
+  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onDelete: () => void;
   onBack: () => void;
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx
index 597bde167..e6c6abc23 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx
@@ -19,13 +19,15 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  HttpError,
+  useTranslationContext,
+} from "@gnu-taler/web-util/lib/index.browser";
 import { 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 { HttpError } from "../../../../utils/request.js";
 import {
   useInstanceReserves,
   useReservesAPI,
@@ -36,7 +38,7 @@ import { CardTable } from "./Table.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (e: HttpError) => VNode;
+  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   onSelect: (id: string) => void;
   onNotFound: () => VNode;
   onCreate: () => void;
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 5fce3a819..0b7c191bd 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
@@ -19,13 +19,15 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  HttpError,
+  useTranslationContext,
+} from "@gnu-taler/web-util/lib/index.browser";
 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 { HttpError } from "../../../../utils/request.js";
 import {
   useInstanceTemplates,
   useTemplateAPI,
@@ -35,7 +37,7 @@ import { ListPage } from "./ListPage.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError) => VNode;
+  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onCreate: () => void;
   onSelect: (id: string) => void;
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 684ffd429..73489869b 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
@@ -19,13 +19,15 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  HttpError,
+  useTranslationContext,
+} from "@gnu-taler/web-util/lib/index.browser";
 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 { HttpError } from "../../../../utils/request.js";
 import {
   useTemplateAPI,
   useTemplateDetails,
@@ -40,7 +42,7 @@ interface Props {
   onConfirm: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError) => VNode;
+  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => 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 cbcadc608..13576d94d 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
@@ -19,7 +19,6 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { h, VNode, FunctionalComponent } from "preact";
 import { UsePage as TestedComponent } from "./UsePage.js";
 
 export default {
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 fa9a98c6d..d5fa6d39d 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
@@ -19,7 +19,10 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  HttpError,
+  useTranslationContext,
+} from "@gnu-taler/web-util/lib/index.browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
@@ -29,7 +32,6 @@ import {
   useTemplateAPI,
   useTemplateDetails,
 } from "../../../../hooks/templates.js";
-import { HttpError } from "../../../../utils/request.js";
 import { Notification } from "../../../../utils/types.js";
 import { UsePage } from "./UsePage.js";
 
@@ -39,7 +41,7 @@ interface Props {
   onOrderCreated: (id: string) => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError) => VNode;
+  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   tid: string;
 }
 
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 59b56a613..9f2b59efd 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
@@ -19,18 +19,18 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
+import { HttpError } from "@gnu-taler/web-util/lib/index.browser.js";
 import { h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
 import { MerchantBackend } from "../../../../declaration.js";
-import { HttpError } from "../../../../utils/request.js";
 import { useInstanceDetails } from "../../../../hooks/instance.js";
 import { useInstanceTransfers } from "../../../../hooks/transfer.js";
 import { ListPage } from "./ListPage.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError) => VNode;
+  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onCreate: () => void;
 }
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 02beb36f2..912393c7c 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
@@ -13,7 +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 { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  HttpError,
+  HttpResponse,
+  useTranslationContext,
+} from "@gnu-taler/web-util/lib/index.browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../components/exception/loading.js";
@@ -26,7 +30,6 @@ import {
   useManagedInstanceDetails,
   useManagementAPI,
 } from "../../../hooks/instance.js";
-import { HttpError, HttpResponse } from "../../../utils/request.js";
 import { Notification } from "../../../utils/types.js";
 import { UpdatePage } from "./UpdatePage.js";
 
@@ -36,8 +39,8 @@ export interface Props {
 
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError) => VNode;
-  onUpdateError: (e: HttpError) => void;
+  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
+  onUpdateError: (e: HttpError<MerchantBackend.ErrorDetail>) => void;
 }
 
 export default function Update(props: Props): VNode {
@@ -63,7 +66,10 @@ function CommonUpdate(
     onUpdateError,
     onUnauthorized,
   }: Props,
-  result: HttpResponse<MerchantBackend.Instances.QueryInstancesResponse>,
+  result: HttpResponse<
+    MerchantBackend.Instances.QueryInstancesResponse,
+    MerchantBackend.ErrorDetail
+  >,
   updateInstance: any,
   clearToken: any,
   setNewToken: any,
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 c5846e4db..670fc7218 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
@@ -19,7 +19,10 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  HttpError,
+  useTranslationContext,
+} from "@gnu-taler/web-util/lib/index.browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
@@ -29,13 +32,12 @@ import {
   useInstanceWebhooks,
   useWebhookAPI,
 } from "../../../../hooks/webhooks.js";
-import { HttpError } from "../../../../utils/request.js";
 import { Notification } from "../../../../utils/types.js";
 import { ListPage } from "./ListPage.js";
 
 interface Props {
   onUnauthorized: () => VNode;
-  onLoadError: (error: HttpError) => VNode;
+  onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   onNotFound: () => VNode;
   onCreate: () => void;
   onSelect: (id: string) => 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 3597fb849..b9a8674b3 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
@@ -19,7 +19,10 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import {
+  HttpError,
+  useTranslationContext,
+} from "@gnu-taler/web-util/lib/index.browser";
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { Loading } from "../../../../components/exception/loading.js";
@@ -29,7 +32,6 @@ import {
   useWebhookAPI,
   useWebhookDetails,
 } from "../../../../hooks/webhooks.js";
-import { HttpError } from "../../../../utils/request.js";
 import { Notification } from "../../../../utils/types.js";
 import { UpdatePage } from "./UpdatePage.js";
 
@@ -40,7 +42,7 @@ interface Props {
   onConfirm: () => void;
   onUnauthorized: () => VNode;
   onNotFound: () => VNode;
-  onLoadError: (e: HttpError) => VNode;
+  onLoadError: (e: HttpError<MerchantBackend.ErrorDetail>) => VNode;
   tid: string;
 }
 export default function UpdateWebhook({
diff --git a/packages/merchant-backoffice-ui/src/utils/request.ts 
b/packages/merchant-backoffice-ui/src/utils/request.ts
deleted file mode 100644
index 821eca4a7..000000000
--- a/packages/merchant-backoffice-ui/src/utils/request.ts
+++ /dev/null
@@ -1,282 +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 axios, { AxiosError, AxiosResponse } from "axios";
-import { MerchantBackend } from "../declaration.js";
-
-export async function defaultRequestHandler<T>(
-  base: string,
-  path: string,
-  options: RequestOptions = {},
-): Promise<HttpResponseOk<T>> {
-  const requestHeaders = options.token
-    ? { Authorization: `Bearer ${options.token}` }
-    : undefined;
-
-  const requestMethod = options?.method ?? "GET";
-  const requestBody = options?.data;
-  const requestTimeout = 2 * 1000;
-  const requestParams = options.params ?? {};
-
-  const _url = new URL(`${base}${path}`);
-
-  Object.entries(requestParams).forEach(([key, value]) => {
-    _url.searchParams.set(key, String(value));
-  });
-
-  let payload: BodyInit | undefined = undefined;
-  if (requestBody != null) {
-    if (typeof requestBody === "string") {
-      payload = requestBody;
-    } else if (requestBody instanceof ArrayBuffer) {
-      payload = requestBody;
-    } else if (ArrayBuffer.isView(requestBody)) {
-      payload = requestBody;
-    } else if (typeof requestBody === "object") {
-      payload = JSON.stringify(requestBody);
-    } else {
-      throw Error("unsupported request body type");
-    }
-  }
-
-  const controller = new AbortController();
-  const timeoutId = setTimeout(() => {
-    controller.abort("HTTP_REQUEST_TIMEOUT");
-  }, requestTimeout);
-
-  const response = await fetch(_url.href, {
-    headers: {
-      ...requestHeaders,
-      "Content-Type": "text/plain",
-    },
-    method: requestMethod,
-    credentials: "omit",
-    mode: "cors",
-    body: payload,
-    signal: controller.signal,
-  });
-
-  if (timeoutId) {
-    clearTimeout(timeoutId);
-  }
-  const headerMap = new Headers();
-  response.headers.forEach((value, key) => {
-    headerMap.set(key, value);
-  });
-
-  if (response.ok) {
-    const result = await buildRequestOk<T>(
-      response,
-      _url,
-      payload,
-      !!options.token,
-    );
-    return result;
-  } else {
-    const error = await buildRequestFailed(
-      response,
-      _url,
-      payload,
-      !!options.token,
-    );
-    throw error;
-  }
-}
-
-export type HttpResponse<T> =
-  | HttpResponseOk<T>
-  | HttpResponseLoading<T>
-  | HttpError;
-export type HttpResponsePaginated<T> =
-  | HttpResponseOkPaginated<T>
-  | HttpResponseLoading<T>
-  | HttpError;
-
-export interface RequestInfo {
-  url: URL;
-  hasToken: boolean;
-  payload: any;
-  status: number;
-}
-
-interface HttpResponseLoading<T> {
-  ok?: false;
-  loading: true;
-  clientError?: false;
-  serverError?: false;
-
-  data?: T;
-}
-export interface HttpResponseOk<T> {
-  ok: true;
-  loading?: false;
-  clientError?: false;
-  serverError?: false;
-
-  data: T;
-  info?: RequestInfo;
-}
-
-export type HttpResponseOkPaginated<T> = HttpResponseOk<T> & WithPagination;
-
-export interface WithPagination {
-  loadMore: () => void;
-  loadMorePrev: () => void;
-  isReachingEnd?: boolean;
-  isReachingStart?: boolean;
-}
-
-export type HttpError =
-  | HttpResponseClientError
-  | HttpResponseServerError
-  | HttpResponseUnexpectedError;
-export interface SwrError {
-  info: unknown;
-  status: number;
-  message: string;
-}
-export interface HttpResponseServerError {
-  ok?: false;
-  loading?: false;
-  clientError?: false;
-  serverError: true;
-
-  error?: MerchantBackend.ErrorDetail;
-  status: number;
-  message: string;
-  info?: RequestInfo;
-}
-interface HttpResponseClientError {
-  ok?: false;
-  loading?: false;
-  clientError: true;
-  serverError?: false;
-
-  info?: RequestInfo;
-  isUnauthorized: boolean;
-  isNotfound: boolean;
-  status: number;
-  error?: MerchantBackend.ErrorDetail;
-  message: string;
-}
-
-interface HttpResponseUnexpectedError {
-  ok?: false;
-  loading?: false;
-  clientError?: false;
-  serverError?: false;
-
-  info?: RequestInfo;
-  status?: number;
-  error: unknown;
-  message: string;
-}
-
-type Methods = "GET" | "POST" | "PATCH" | "DELETE" | "PUT";
-
-export interface RequestOptions {
-  method?: Methods;
-  token?: string;
-  data?: any;
-  params?: unknown;
-}
-
-async function buildRequestOk<T>(
-  response: Response,
-  url: URL,
-  payload: any,
-  hasToken: boolean,
-): Promise<HttpResponseOk<T>> {
-  const dataTxt = await response.text();
-  const data = dataTxt ? JSON.parse(dataTxt) : undefined;
-  return {
-    ok: true,
-    data,
-    info: {
-      payload,
-      url,
-      hasToken,
-      status: response.status,
-    },
-  };
-}
-
-async function buildRequestFailed(
-  response: Response,
-  url: URL,
-  payload: any,
-  hasToken: boolean,
-): Promise<
-  | HttpResponseClientError
-  | HttpResponseServerError
-  | HttpResponseUnexpectedError
-> {
-  const status = response?.status;
-
-  const info: RequestInfo = {
-    payload,
-    url,
-    hasToken,
-    status: status || 0,
-  };
-
-  try {
-    const dataTxt = await response.text();
-    const data = dataTxt ? JSON.parse(dataTxt) : undefined;
-    if (status && status >= 400 && status < 500) {
-      const error: HttpResponseClientError = {
-        clientError: true,
-        isNotfound: status === 404,
-        isUnauthorized: status === 401,
-        status,
-        info,
-        message: data?.hint,
-        error: data,
-      };
-      return error;
-    }
-    if (status && status >= 500 && status < 600) {
-      const error: HttpResponseServerError = {
-        serverError: true,
-        status,
-        info,
-        message: `${data?.hint} (code ${data?.code})`,
-        error: data,
-      };
-      return error;
-    }
-    return {
-      info,
-      status,
-      error: {},
-      message: "NOT DEFINED",
-    };
-  } catch (ex) {
-    const error: HttpResponseUnexpectedError = {
-      info,
-      status,
-      error: ex,
-      message: "NOT DEFINED",
-    };
-
-    throw error;
-  }
-}
-
-// export function isAxiosError<T>(
-//   error: AxiosError | any,
-// ): error is AxiosError<T> {
-//   return error && error.isAxiosError;
-// }

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