gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 02/02: wip #8489


From: gnunet
Subject: [taler-wallet-core] 02/02: wip #8489
Date: Fri, 08 Mar 2024 16:19:29 +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 e0e82cdf07930d766081e42203c5a4e66d43191f
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Fri Mar 8 12:19:20 2024 -0300

    wip #8489
---
 .../auditor-backoffice-ui/src/hooks/testing.tsx    |   8 +-
 packages/demobank-ui/src/Routing.tsx               |   9 +-
 packages/demobank-ui/src/context/config.ts         | 201 ++++++++++-----------
 packages/demobank-ui/src/hooks/account.ts          |  12 +-
 packages/demobank-ui/src/hooks/regional.ts         |  28 +--
 packages/demobank-ui/src/pages/LoginForm.tsx       |   5 +-
 .../demobank-ui/src/pages/OperationState/state.ts  |  10 +-
 .../src/pages/PaytoWireTransferForm.tsx            |   2 +-
 packages/demobank-ui/src/pages/QrCodeSection.tsx   |   2 +-
 .../demobank-ui/src/pages/RegistrationPage.tsx     |   2 +-
 .../demobank-ui/src/pages/SolveChallengePage.tsx   |   2 +-
 .../demobank-ui/src/pages/WalletWithdrawForm.tsx   |   2 +-
 .../src/pages/WithdrawalConfirmationQuestion.tsx   |   2 +-
 .../src/pages/WithdrawalOperationPage.tsx          |   4 +-
 .../src/pages/account/ShowAccountDetails.tsx       |   2 +-
 .../src/pages/account/UpdateAccountPassword.tsx    |   2 +-
 .../src/pages/admin/CreateNewAccount.tsx           |   2 +-
 .../demobank-ui/src/pages/admin/DownloadStats.tsx  |   2 +-
 .../demobank-ui/src/pages/admin/RemoveAccount.tsx  |   2 +-
 .../src/pages/regional/ConversionConfig.tsx        |   6 +-
 .../src/pages/regional/CreateCashout.tsx           |   2 +-
 .../merchant-backoffice-ui/src/hooks/testing.tsx   |   8 +-
 .../taler-util/src/http-client/bank-conversion.ts  |  13 +-
 packages/taler-util/src/http-client/bank-core.ts   |  78 ++++----
 packages/taler-util/src/http-client/utils.ts       |   8 +
 packages/taler-util/src/index.ts                   |   1 +
 26 files changed, 213 insertions(+), 202 deletions(-)

diff --git a/packages/auditor-backoffice-ui/src/hooks/testing.tsx 
b/packages/auditor-backoffice-ui/src/hooks/testing.tsx
index 3ea22475b..20b9c8a35 100644
--- a/packages/auditor-backoffice-ui/src/hooks/testing.tsx
+++ b/packages/auditor-backoffice-ui/src/hooks/testing.tsx
@@ -27,7 +27,7 @@ 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 } from 
"@gnu-taler/taler-util";
+import { TalerBankIntegrationHttpClient, TalerCoreBankHttpClient, 
TalerRevenueHttpClient, TalerWireGatewayHttpClient } from 
"@gnu-taler/taler-util";
 
 export class ApiMockEnvironment extends MockEnvironment {
   constructor(debug = false) {
@@ -144,9 +144,9 @@ export class ApiMockEnvironment extends MockEnvironment {
 
       }
       const bankCore = new TalerCoreBankHttpClient("http://localhost";, 
mockHttpClient)
-      const bankIntegration = bankCore.getIntegrationAPI()
-      const bankRevenue = bankCore.getRevenueAPI("a")
-      const bankWire = bankCore.getWireGatewayAPI("b")
+      const bankIntegration = new 
TalerBankIntegrationHttpClient(bankCore.getIntegrationAPI(), mockHttpClient)
+      const bankRevenue = new 
TalerRevenueHttpClient(bankCore.getRevenueAPI("a"), "a", mockHttpClient)
+      const bankWire = new 
TalerWireGatewayHttpClient(bankCore.getWireGatewayAPI("b"), "b", mockHttpClient)
 
       return (
         <BackendContextProvider defaultUrl="http://backend";>
diff --git a/packages/demobank-ui/src/Routing.tsx 
b/packages/demobank-ui/src/Routing.tsx
index c85d74e17..f9b388ed1 100644
--- a/packages/demobank-ui/src/Routing.tsx
+++ b/packages/demobank-ui/src/Routing.tsx
@@ -94,7 +94,7 @@ function PublicRounting({
   const { i18n } = useTranslationContext();
   const location = useCurrentLocation(publicPages);
   const { navigateTo } = useNavigationContext();
-  const { api } = useBankCoreApiContext();
+  const { bank, authenticator } = useBankCoreApiContext();
   const [notification, notify, handleError] = useLocalNotification();
 
   useEffect(() => {
@@ -109,8 +109,7 @@ function PublicRounting({
 
   async function doAutomaticLogin(username: string, password: string) {
     await handleError(async () => {
-      const resp = await api
-        .getAuthenticationAPI(username)
+      const resp = await authenticator(username)
         .createAccessToken(password, {
           scope: "readwrite",
           duration: { d_us: "forever" },
@@ -570,11 +569,11 @@ function PrivateRouting({
         routeMyAccountDetails={privatePages.myAccountDetails}
         routeMyAccountPassword={privatePages.myAccountPassword}
         routeConversionConfig={privatePages.conversionConfig}
-        routeCancel={privatePages.home} 
+        routeCancel={privatePages.home}
         onUpdateSuccess={() => {
           navigateTo(privatePages.home.url({}))
         }}
-        />;
+      />;
     }
     case "homeWireTransfer": {
       return (
diff --git a/packages/demobank-ui/src/context/config.ts 
b/packages/demobank-ui/src/context/config.ts
index 72c176679..39d12be86 100644
--- a/packages/demobank-ui/src/context/config.ts
+++ b/packages/demobank-ui/src/context/config.ts
@@ -15,20 +15,16 @@
  */
 
 import {
-  AccessToken,
-  AmountJson,
-  HttpStatusCode,
+  assertUnreachable,
   LibtoolVersion,
-  OperationFail,
-  OperationOk,
-  TalerBankConversionApi,
+  TalerBankConversionCacheEviction,
   TalerBankConversionHttpClient,
   TalerCorebankApi,
+  TalerAuthenticationHttpClient,
+  TalerCoreBankCacheEviction,
   TalerCoreBankHttpClient,
-  TalerError,
-  UserAndToken,
+  TalerError
 } from "@gnu-taler/taler-util";
-import { HttpRequestLibrary } from "@gnu-taler/taler-util/http";
 import {
   BrowserHttpLib,
   ErrorLoading,
@@ -61,7 +57,9 @@ import {
 export type Type = {
   url: URL;
   config: TalerCorebankApi.Config;
-  api: TalerCoreBankHttpClient;
+  bank: TalerCoreBankHttpClient;
+  conversion: TalerBankConversionHttpClient;
+  authenticator: (user: string) => TalerAuthenticationHttpClient;
   hints: VersionHint[];
 };
 
@@ -95,13 +93,14 @@ export const BankCoreApiProvider = ({
 }): VNode => {
   const [checked, setChecked] = useState<ConfigResult>();
   const { i18n } = useTranslationContext();
-  const url = new URL(baseUrl);
-  const api = new CacheAwareTalerCoreBankHttpClient(url.href, new 
BrowserHttpLib());
+
+  const { bankClient, conversionClient, authClient } = buildApiClient(new 
URL(baseUrl))
+
   useEffect(() => {
-    api
+    bankClient
       .getConfig()
       .then((resp) => {
-        if (api.isCompatible(resp.body.version)) {
+        if (bankClient.isCompatible(resp.body.version)) {
           setChecked({ type: "ok", config: resp.body, hints: [] });
         } else {
           // this API supports version 3.0.3
@@ -116,7 +115,7 @@ export const BankCoreApiProvider = ({
             setChecked({
               type: "incompatible",
               result: resp.body,
-              supported: api.PROTOCOL_VERSION,
+              supported: bankClient.PROTOCOL_VERSION,
             });
           }
         }
@@ -146,9 +145,11 @@ export const BankCoreApiProvider = ({
     });
   }
   const value: Type = {
-    url,
+    url: new URL(bankClient.baseUrl),
     config: checked.config,
-    api: api,
+    bank: bankClient,
+    conversion: conversionClient,
+    authenticator: authClient,
     hints: checked.hints,
   };
   return h(Context.Provider, {
@@ -158,100 +159,84 @@ export const BankCoreApiProvider = ({
 };
 
 /**
- * 
+ * build http client with cache breaker due to SWR
+ * @param url 
+ * @returns 
  */
-class CacheAwareTalerBankConversionHttpClient extends 
TalerBankConversionHttpClient {
-  constructor(baseUrl: string, httpClient?: HttpRequestLibrary) {
-    super(baseUrl, httpClient);
-  }
-  async updateConversionRate(auth: AccessToken, body: 
TalerBankConversionApi.ConversionRate) {
-    const resp = await super.updateConversionRate(auth, body);
-    if (resp.type === "ok") {
-      await revalidateConversionInfo();
-    }
-    return resp
-  }
-}
+function buildApiClient(url: URL) {
+  const httpLib = new BrowserHttpLib();
 
-class CacheAwareTalerCoreBankHttpClient extends TalerCoreBankHttpClient {
-  constructor(baseUrl: string, httpClient?: HttpRequestLibrary) {
-    super(baseUrl, httpClient);
-  }
-  async deleteAccount(auth: UserAndToken, cid?: string | undefined) {
-    const resp = await super.deleteAccount(auth, cid);
-    if (resp.type === "ok") {
-      await revalidatePublicAccounts();
-      await revalidateBusinessAccounts();
-    }
-    return resp;
-  }
-  async createAccount(
-    auth: AccessToken,
-    body: TalerCorebankApi.RegisterAccountRequest,
-  ) {
-    const resp = await super.createAccount(auth, body);
-    if (resp.type === "ok") {
-      // admin balance change on new account
-      await revalidateAccountDetails();
-      await revalidateTransactions();
-      await revalidatePublicAccounts();
-      await revalidateBusinessAccounts();
-    }
-    return resp;
-  }
-  async updateAccount(
-    auth: UserAndToken,
-    body: TalerCorebankApi.AccountReconfiguration,
-    cid?: string | undefined,
-  ) {
-    const resp = await super.updateAccount(auth, body, cid);
-    if (resp.type === "ok") {
-      await revalidateAccountDetails();
-    }
-    return resp;
-  }
-  async createTransaction(
-    auth: UserAndToken,
-    body: TalerCorebankApi.CreateTransactionRequest,
-    cid?: string | undefined,
-  ) {
-    const resp = await super.createTransaction(auth, body, cid);
-    if (resp.type === "ok") {
-      await revalidateAccountDetails();
-      await revalidateTransactions();
-    }
-    return resp;
-  }
-  async confirmWithdrawalById(
-    auth: UserAndToken,
-    wid: string,
-    cid?: string | undefined,
-  ) {
-    const resp = await super.confirmWithdrawalById(auth, wid, cid);
-    if (resp.type === "ok") {
-      await revalidateAccountDetails();
-      await revalidateTransactions();
+  const bankClient = new TalerCoreBankHttpClient(url.href, httpLib, {
+    async notifySuccess(op) {
+      switch (op) {
+        case TalerCoreBankCacheEviction.DELELE_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)
+      }
     }
-    return resp;
-  }
-  async createCashout(
-    auth: UserAndToken,
-    body: TalerCorebankApi.CashoutRequest,
-    cid?: string | undefined,
-  ) {
-    const resp = await super.createCashout(auth, body, cid);
-    if (resp.type === "ok") {
-      await revalidateAccountDetails();
-      await revalidateCashouts();
-      await revalidateTransactions();
+  });
+  const conversionClient = new 
TalerBankConversionHttpClient(bankClient.getConversionInfoAPI(), httpLib, {
+    async notifySuccess(op) {
+      switch (op) {
+        case TalerBankConversionCacheEviction.UPDATE_RATE: {
+          await revalidateConversionInfo();
+          return
+        }
+        default:
+          assertUnreachable(op)
+      }
     }
-    return resp;
-  }
-
-  getConversionInfoAPI(): TalerBankConversionHttpClient {
-    const api = super.getConversionInfoAPI();
-    return new CacheAwareTalerBankConversionHttpClient(api.baseUrl, 
this.httpLib)
-  }
+  });
+  const authClient = (user: string) => new 
TalerAuthenticationHttpClient(bankClient.getAuthenticationAPI(user), user, 
httpLib);
+  return { bankClient, conversionClient, authClient }
 }
 
 export const BankCoreApiProviderTesting = ({
@@ -267,7 +252,7 @@ export const BankCoreApiProviderTesting = ({
     url: new URL(url),
     config: state,
     // @ts-expect-error this API is not being used, not really needed
-    api: undefined,
+    bank: undefined,
     hints: [],
   };
 
diff --git a/packages/demobank-ui/src/hooks/account.ts 
b/packages/demobank-ui/src/hooks/account.ts
index 61a11b1a5..aa0745253 100644
--- a/packages/demobank-ui/src/hooks/account.ts
+++ b/packages/demobank-ui/src/hooks/account.ts
@@ -44,7 +44,7 @@ export function revalidateAccountDetails() {
 
 export function useAccountDetails(account: string) {
   const { state: credentials } = useSessionState();
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
 
   async function fetcher([username, token]: [string, AccessToken]) {
     return await api.getAccount({ username, token });
@@ -66,7 +66,7 @@ export function revalidateWithdrawalDetails() {
 }
 
 export function useWithdrawalDetails(wid: string) {
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
   const [latestStatus, setLatestStatus] = 
useState<WithdrawalOperationStatus>();
 
   async function fetcher([wid, old_state]: [
@@ -117,7 +117,7 @@ export function useTransactionDetails(account: string, tid: 
number) {
   const { state: credentials } = useSessionState();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
 
   async function fetcher([username, token, txid]: [
     string,
@@ -147,7 +147,7 @@ export function useTransactionDetails(account: string, tid: 
number) {
   return undefined;
 }
 
-export function revalidatePublicAccounts() {
+export async function revalidatePublicAccounts() {
   return mutate(
     (key) => Array.isArray(key) && key[key.length - 1] === 
"getPublicAccounts", undefined, { revalidate: true }
   );
@@ -158,7 +158,7 @@ export function usePublicAccounts(
 ) {
   const [offset, setOffset] = useState<number | undefined>(initial);
 
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
 
   async function fetcher([account, txid]: [
     string | undefined,
@@ -233,7 +233,7 @@ export function useTransactions(account: string, initial?: 
number) {
     credentials.status !== "loggedIn" ? undefined : credentials.token;
 
   const [offset, setOffset] = useState<number | undefined>(initial);
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
 
   async function fetcher([username, token, txid]: [
     string,
diff --git a/packages/demobank-ui/src/hooks/regional.ts 
b/packages/demobank-ui/src/hooks/regional.ts
index 3469bf501..bf948d293 100644
--- a/packages/demobank-ui/src/hooks/regional.ts
+++ b/packages/demobank-ui/src/hooks/regional.ts
@@ -60,10 +60,10 @@ export function revalidateConversionInfo() {
   );
 }
 export function useConversionInfo() {
-  const { api, config } = useBankCoreApiContext();
+  const { conversion, config } = useBankCoreApiContext();
 
   async function fetcher() {
-    return await api.getConversionInfoAPI().getConfig();
+    return await conversion.getConfig();
   }
   const { data, error } = useSWR<
     TalerBankConversionResultByMethod<"getConfig">,
@@ -86,10 +86,10 @@ export function useConversionInfo() {
 }
 
 export function useCashinEstimator(): ConversionEstimators {
-  const { api } = useBankCoreApiContext();
+  const { conversion } = useBankCoreApiContext();
   return {
     estimateByCredit: async (fiatAmount, fee) => {
-      const resp = await api.getConversionInfoAPI().getCashinRate({
+      const resp = await conversion.getCashinRate({
         credit: fiatAmount,
       });
       if (resp.type === "fail") {
@@ -114,7 +114,7 @@ export function useCashinEstimator(): ConversionEstimators {
       };
     },
     estimateByDebit: async (regionalAmount, fee) => {
-      const resp = await api.getConversionInfoAPI().getCashinRate({
+      const resp = await conversion.getCashinRate({
         debit: regionalAmount,
       });
       if (resp.type === "fail") {
@@ -142,10 +142,10 @@ export function useCashinEstimator(): 
ConversionEstimators {
 }
 
 export function useCashoutEstimator(): ConversionEstimators {
-  const { api } = useBankCoreApiContext();
+  const { bank, conversion } = useBankCoreApiContext();
   return {
     estimateByCredit: async (fiatAmount, fee) => {
-      const resp = await api.getConversionInfoAPI().getCashoutRate({
+      const resp = await conversion.getCashoutRate({
         credit: fiatAmount,
       });
       if (resp.type === "fail") {
@@ -170,7 +170,7 @@ export function useCashoutEstimator(): ConversionEstimators 
{
       };
     },
     estimateByDebit: async (regionalAmount, fee) => {
-      const resp = await api.getConversionInfoAPI().getCashoutRate({
+      const resp = await conversion.getCashoutRate({
         debit: regionalAmount,
       });
       if (resp.type === "fail") {
@@ -204,14 +204,14 @@ export function useEstimator(): ConversionEstimators {
   return useCashoutEstimator()
 }
 
-export function revalidateBusinessAccounts() {
+export async function revalidateBusinessAccounts() {
   return mutate((key) => Array.isArray(key) && key[key.length - 1] === 
"getAccounts", undefined, { revalidate: true });
 }
 export function useBusinessAccounts() {
   const { state: credentials } = useSessionState();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
 
   const [offset, setOffset] = useState<number | undefined>();
 
@@ -281,7 +281,7 @@ export function revalidateOnePendingCashouts() {
 }
 export function useOnePendingCashouts(account: string) {
   const { state: credentials } = useSessionState();
-  const { api, config } = useBankCoreApiContext();
+  const { bank: api, config } = useBankCoreApiContext();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
 
@@ -338,7 +338,7 @@ export function revalidateCashouts() {
 }
 export function useCashouts(account: string) {
   const { state: credentials } = useSessionState();
-  const { api, config } = useBankCoreApiContext();
+  const { bank: api, config } = useBankCoreApiContext();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
 
@@ -392,7 +392,7 @@ export function revalidateCashoutDetails() {
 export function useCashoutDetails(cashoutId: number | undefined) {
   const { state: credentials } = useSessionState();
   const creds = credentials.status !== "loggedIn" ? undefined : credentials;
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
 
   async function fetcher([username, token, id]: [string, AccessToken, number]) 
{
     return api.getCashoutById({ username, token }, id);
@@ -443,7 +443,7 @@ export function useLastMonitorInfo(
   previousMoment: number,
   timeframe: TalerCorebankApi.MonitorTimeframeParam,
 ) {
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
   const { state: credentials } = useSessionState();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
diff --git a/packages/demobank-ui/src/pages/LoginForm.tsx 
b/packages/demobank-ui/src/pages/LoginForm.tsx
index e62759415..bd20e79c8 100644
--- a/packages/demobank-ui/src/pages/LoginForm.tsx
+++ b/packages/demobank-ui/src/pages/LoginForm.tsx
@@ -53,7 +53,7 @@ export function LoginForm({
   );
   const [password, setPassword] = useState<string | undefined>();
   const { i18n } = useTranslationContext();
-  const { api } = useBankCoreApiContext();
+  const { authenticator } = useBankCoreApiContext();
   const [notification, withErrorHandler] = useLocalNotificationHandler();
   const { config } = useBankCoreApiContext();
 
@@ -77,8 +77,7 @@ export function LoginForm({
   }
 
   const loginHandler = !username || !password ? undefined : withErrorHandler(
-    async () => api
-      .getAuthenticationAPI(username)
+    async () => authenticator(username)
       .createAccessToken(password, {
         // scope: "readwrite" as "write", // FIX: different than merchant
         scope: "readwrite",
diff --git a/packages/demobank-ui/src/pages/OperationState/state.ts 
b/packages/demobank-ui/src/pages/OperationState/state.ts
index 693179d40..5baf2d51c 100644
--- a/packages/demobank-ui/src/pages/OperationState/state.ts
+++ b/packages/demobank-ui/src/pages/OperationState/state.ts
@@ -45,7 +45,7 @@ export function useComponentState({
   const [bankState, updateBankState] = useBankState();
   const { state: credentials } = useSessionState();
   const creds = credentials.status !== "loggedIn" ? undefined : credentials;
-  const { api } = useBankCoreApiContext();
+  const { bank } = useBankCoreApiContext();
 
   const [failure, setFailure] = useState<
     TalerCoreBankErrorsByMethod<"createWithdrawal"> | undefined
@@ -56,7 +56,7 @@ export function useComponentState({
     // FIXME: if amount is not enough use balance
     const parsedAmount = Amounts.parseOrThrow(`${currency}:${amount}`);
     if (!creds) return;
-    const resp = await api.createWithdrawal(creds, {
+    const resp = await bank.createWithdrawal(creds, {
       amount: Amounts.stringify(parsedAmount),
     });
     if (resp.type === "fail") {
@@ -91,7 +91,7 @@ export function useComponentState({
 
   async function doAbort() {
     if (!creds) return;
-    const resp = await api.abortWithdrawalById(creds, wid);
+    const resp = await bank.abortWithdrawalById(creds, wid);
     if (resp.type === "ok") {
       // updateBankState("currentWithdrawalOperationId", undefined)
       onAbort();
@@ -104,7 +104,7 @@ export function useComponentState({
     TalerCoreBankErrorsByMethod<"confirmWithdrawalById"> | undefined
   > {
     if (!creds) return;
-    const resp = await api.confirmWithdrawalById(creds, wid);
+    const resp = await bank.confirmWithdrawalById(creds, wid);
     if (resp.type === "ok") {
       mutate(() => true); //clean withdrawal state
     } else {
@@ -113,7 +113,7 @@ export function useComponentState({
   }
 
   const uri = stringifyWithdrawUri({
-    bankIntegrationApiBaseUrl: api.getIntegrationAPI().baseUrl,
+    bankIntegrationApiBaseUrl: bank.getIntegrationAPI(),
     withdrawalOperationId,
   });
   const parsedUri = parseWithdrawUri(uri);
diff --git a/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx 
b/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx
index f746094ce..791a3b440 100644
--- a/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx
+++ b/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx
@@ -81,7 +81,7 @@ export function PaytoWireTransferForm({
 }: Props): VNode {
   const [isRawPayto, setIsRawPayto] = useState(false);
   const { state: credentials } = useSessionState();
-  const { api, config, url } = useBankCoreApiContext();
+  const { bank: api, config, url } = useBankCoreApiContext();
 
   const sendingToFixedAccount = withAccount !== undefined;
 
diff --git a/packages/demobank-ui/src/pages/QrCodeSection.tsx 
b/packages/demobank-ui/src/pages/QrCodeSection.tsx
index d4f5a5455..da11e631d 100644
--- a/packages/demobank-ui/src/pages/QrCodeSection.tsx
+++ b/packages/demobank-ui/src/pages/QrCodeSection.tsx
@@ -51,7 +51,7 @@ export function QrCodeSection({
 
   const [notification, handleError] = useLocalNotificationHandler();
 
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
 
   const onAbortHandler = handleError(
     async () => {
diff --git a/packages/demobank-ui/src/pages/RegistrationPage.tsx 
b/packages/demobank-ui/src/pages/RegistrationPage.tsx
index 18b4c470b..e9f7e602f 100644
--- a/packages/demobank-ui/src/pages/RegistrationPage.tsx
+++ b/packages/demobank-ui/src/pages/RegistrationPage.tsx
@@ -80,7 +80,7 @@ function RegistrationForm({
   const [notification, _, handleError] = useLocalNotification();
   const settings = useSettingsContext();
 
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
   // const { register } = useTestingAPI();
   const { i18n } = useTranslationContext();
 
diff --git a/packages/demobank-ui/src/pages/SolveChallengePage.tsx 
b/packages/demobank-ui/src/pages/SolveChallengePage.tsx
index 7e117f535..b2e053b3c 100644
--- a/packages/demobank-ui/src/pages/SolveChallengePage.tsx
+++ b/packages/demobank-ui/src/pages/SolveChallengePage.tsx
@@ -57,7 +57,7 @@ export function SolveChallengePage({
   onChallengeCompleted: () => void;
   routeClose: RouteDefinition;
 }): VNode {
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
   const { i18n } = useTranslationContext();
   const [bankState, updateBankState] = useBankState();
   const [code, setCode] = useState<string | undefined>(undefined);
diff --git a/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx 
b/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx
index caf205f31..001d90fa1 100644
--- a/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx
+++ b/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx
@@ -63,7 +63,7 @@ function OldWithdrawalForm({
   // const { navigateTo } = useNavigationContext();
 
   const [bankState, updateBankState] = useBankState();
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
 
   const { state: credentials } = useSessionState();
   const creds = credentials.status !== "loggedIn" ? undefined : credentials;
diff --git a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx 
b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
index 4efc82017..5925719c3 100644
--- a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
+++ b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
@@ -74,7 +74,7 @@ export function WithdrawalConfirmationQuestion({
 
   const [notification, notify, handleError] = useLocalNotification();
 
-  const { config, api } = useBankCoreApiContext();
+  const { config, bank: api } = useBankCoreApiContext();
 
   async function doTransfer() {
     await handleError(async () => {
diff --git a/packages/demobank-ui/src/pages/WithdrawalOperationPage.tsx 
b/packages/demobank-ui/src/pages/WithdrawalOperationPage.tsx
index 7075c34c6..973a23011 100644
--- a/packages/demobank-ui/src/pages/WithdrawalOperationPage.tsx
+++ b/packages/demobank-ui/src/pages/WithdrawalOperationPage.tsx
@@ -36,9 +36,9 @@ export function WithdrawalOperationPage({
   routeClose: RouteDefinition;
   routeWithdrawalDetails: RouteDefinition<{ wopid: string }>;
 }): VNode {
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
   const uri = stringifyWithdrawUri({
-    bankIntegrationApiBaseUrl: api.getIntegrationAPI().baseUrl,
+    bankIntegrationApiBaseUrl: api.getIntegrationAPI(),
     withdrawalOperationId: operationId,
   });
   const parsedUri = parseWithdrawUri(uri);
diff --git a/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx 
b/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx
index 8ab3998ad..62c8df7f8 100644
--- a/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx
+++ b/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx
@@ -67,7 +67,7 @@ export function ShowAccountDetails({
   const { i18n } = useTranslationContext();
   const { state: credentials } = useSessionState();
   const creds = credentials.status !== "loggedIn" ? undefined : credentials;
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
   const accountIsTheCurrentUser =
     credentials.status === "loggedIn"
       ? credentials.username === account
diff --git a/packages/demobank-ui/src/pages/account/UpdateAccountPassword.tsx 
b/packages/demobank-ui/src/pages/account/UpdateAccountPassword.tsx
index b9a334088..e21ac2464 100644
--- a/packages/demobank-ui/src/pages/account/UpdateAccountPassword.tsx
+++ b/packages/demobank-ui/src/pages/account/UpdateAccountPassword.tsx
@@ -65,7 +65,7 @@ export function UpdateAccountPassword({
   const { state: credentials } = useSessionState();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
 
   const [current, setCurrent] = useState<string | undefined>();
   const [password, setPassword] = useState<string | undefined>();
diff --git a/packages/demobank-ui/src/pages/admin/CreateNewAccount.tsx 
b/packages/demobank-ui/src/pages/admin/CreateNewAccount.tsx
index 3ae2b636c..38119735e 100644
--- a/packages/demobank-ui/src/pages/admin/CreateNewAccount.tsx
+++ b/packages/demobank-ui/src/pages/admin/CreateNewAccount.tsx
@@ -45,7 +45,7 @@ export function CreateNewAccount({
   const { state: credentials } = useSessionState();
   const token =
     credentials.status !== "loggedIn" ? undefined : credentials.token;
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
 
   const [submitAccount, setSubmitAccount] = useState<
     TalerCorebankApi.RegisterAccountRequest | undefined
diff --git a/packages/demobank-ui/src/pages/admin/DownloadStats.tsx 
b/packages/demobank-ui/src/pages/admin/DownloadStats.tsx
index 66ef73d19..fba366676 100644
--- a/packages/demobank-ui/src/pages/admin/DownloadStats.tsx
+++ b/packages/demobank-ui/src/pages/admin/DownloadStats.tsx
@@ -59,7 +59,7 @@ export function DownloadStats({ routeCancel }: Props): VNode {
     credentials.status !== "loggedIn" || !credentials.isUserAdministrator
       ? undefined
       : credentials;
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
 
   const [options, setOptions] = useState<Options>({
     compareWithPrevious: true,
diff --git a/packages/demobank-ui/src/pages/admin/RemoveAccount.tsx 
b/packages/demobank-ui/src/pages/admin/RemoveAccount.tsx
index 6039db326..61def9a95 100644
--- a/packages/demobank-ui/src/pages/admin/RemoveAccount.tsx
+++ b/packages/demobank-ui/src/pages/admin/RemoveAccount.tsx
@@ -64,7 +64,7 @@ export function RemoveAccount({
 
   const { state } = useSessionState();
   const token = state.status !== "loggedIn" ? undefined : state.token;
-  const { api } = useBankCoreApiContext();
+  const { bank: api } = useBankCoreApiContext();
   const [notification, notify, handleError] = useLocalNotification();
   const [, updateBankState] = useBankState();
 
diff --git a/packages/demobank-ui/src/pages/regional/ConversionConfig.tsx 
b/packages/demobank-ui/src/pages/regional/ConversionConfig.tsx
index 63423353b..8845ec9a0 100644
--- a/packages/demobank-ui/src/pages/regional/ConversionConfig.tsx
+++ b/packages/demobank-ui/src/pages/regional/ConversionConfig.tsx
@@ -88,7 +88,7 @@ function useComponentState({
   return () => {
     const { i18n } = useTranslationContext();
 
-    const { api, config } = useBankCoreApiContext();
+    const { bank, conversion, config } = useBankCoreApiContext();
 
     const [notification, notify, handleError] = useLocalNotification();
 
@@ -153,9 +153,7 @@ function useComponentState({
       if (!creds) return
       await handleError(async () => {
         if (status.status === "fail") return;
-        const resp = await api
-          .getConversionInfoAPI()
-          .updateConversionRate(creds.token, status.result.conv)
+        const resp = await conversion.updateConversionRate(creds.token, 
status.result.conv)
         if (resp.type === "ok") {
           setSection("detail")
         } else {
diff --git a/packages/demobank-ui/src/pages/regional/CreateCashout.tsx 
b/packages/demobank-ui/src/pages/regional/CreateCashout.tsx
index a5b8f774a..2f15d16b4 100644
--- a/packages/demobank-ui/src/pages/regional/CreateCashout.tsx
+++ b/packages/demobank-ui/src/pages/regional/CreateCashout.tsx
@@ -86,7 +86,7 @@ export function CreateCashout({
   const creds = credentials.status !== "loggedIn" ? undefined : credentials;
   const [, updateBankState] = useBankState();
 
-  const { api, config, hints } = useBankCoreApiContext();
+  const { bank: api, config, hints } = useBankCoreApiContext();
   const [form, setForm] = useState<Partial<FormType>>({ isDebit: true });
   const [notification, notify, handleError] = useLocalNotification();
   const info = useConversionInfo();
diff --git a/packages/merchant-backoffice-ui/src/hooks/testing.tsx 
b/packages/merchant-backoffice-ui/src/hooks/testing.tsx
index 3ea22475b..20b9c8a35 100644
--- a/packages/merchant-backoffice-ui/src/hooks/testing.tsx
+++ b/packages/merchant-backoffice-ui/src/hooks/testing.tsx
@@ -27,7 +27,7 @@ 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 } from 
"@gnu-taler/taler-util";
+import { TalerBankIntegrationHttpClient, TalerCoreBankHttpClient, 
TalerRevenueHttpClient, TalerWireGatewayHttpClient } from 
"@gnu-taler/taler-util";
 
 export class ApiMockEnvironment extends MockEnvironment {
   constructor(debug = false) {
@@ -144,9 +144,9 @@ export class ApiMockEnvironment extends MockEnvironment {
 
       }
       const bankCore = new TalerCoreBankHttpClient("http://localhost";, 
mockHttpClient)
-      const bankIntegration = bankCore.getIntegrationAPI()
-      const bankRevenue = bankCore.getRevenueAPI("a")
-      const bankWire = bankCore.getWireGatewayAPI("b")
+      const bankIntegration = new 
TalerBankIntegrationHttpClient(bankCore.getIntegrationAPI(), mockHttpClient)
+      const bankRevenue = new 
TalerRevenueHttpClient(bankCore.getRevenueAPI("a"), "a", mockHttpClient)
+      const bankWire = new 
TalerWireGatewayHttpClient(bankCore.getWireGatewayAPI("b"), "b", mockHttpClient)
 
       return (
         <BackendContextProvider defaultUrl="http://backend";>
diff --git a/packages/taler-util/src/http-client/bank-conversion.ts 
b/packages/taler-util/src/http-client/bank-conversion.ts
index 91d07b11b..ea247ccfc 100644
--- a/packages/taler-util/src/http-client/bank-conversion.ts
+++ b/packages/taler-util/src/http-client/bank-conversion.ts
@@ -39,7 +39,7 @@ import {
   codecForCashoutConversionResponse,
   codecForConversionBankConfig,
 } from "./types.js";
-import { makeBearerTokenAuthHeader } from "./utils.js";
+import { CacheEvictor, makeBearerTokenAuthHeader, nullEvictor } from 
"./utils.js";
 
 export type TalerBankConversionResultByMethod<
   prop extends keyof TalerBankConversionHttpClient,
@@ -48,6 +48,10 @@ export type TalerBankConversionErrorsByMethod<
   prop extends keyof TalerBankConversionHttpClient,
 > = FailCasesByMethod<TalerBankConversionHttpClient, prop>;
 
+export enum TalerBankConversionCacheEviction {
+  UPDATE_RATE,
+}
+
 /**
  * The API is used by the wallets.
  */
@@ -55,12 +59,15 @@ export class TalerBankConversionHttpClient {
   public readonly PROTOCOL_VERSION = "0:0:0";
 
   httpLib: HttpRequestLibrary;
+  cacheEvictor: CacheEvictor<TalerBankConversionCacheEviction>;
 
   constructor(
     readonly baseUrl: string,
     httpClient?: HttpRequestLibrary,
+    cacheEvictor?: CacheEvictor<TalerBankConversionCacheEviction>,
   ) {
     this.httpLib = httpClient ?? createPlatformHttpLib();
+    this.cacheEvictor = cacheEvictor ?? nullEvictor;
   }
 
   isCompatible(version: string): boolean {
@@ -195,8 +202,10 @@ export class TalerBankConversionHttpClient {
       body,
     });
     switch (resp.status) {
-      case HttpStatusCode.NoContent:
+      case HttpStatusCode.NoContent: {
+        
this.cacheEvictor.notifySuccess(TalerBankConversionCacheEviction.UPDATE_RATE);
         return opEmptySuccess(resp);
+      }
       case HttpStatusCode.Unauthorized:
         return opKnownHttpFailure(resp.status, resp);
       case HttpStatusCode.NotImplemented:
diff --git a/packages/taler-util/src/http-client/bank-core.ts 
b/packages/taler-util/src/http-client/bank-core.ts
index 40e29dcef..4131edb11 100644
--- a/packages/taler-util/src/http-client/bank-core.ts
+++ b/packages/taler-util/src/http-client/bank-core.ts
@@ -38,11 +38,6 @@ import {
   opSuccessFromHttp,
   opUnknownFailure,
 } from "../operation.js";
-import { TalerAuthenticationHttpClient } from "./authentication.js";
-import { TalerBankConversionHttpClient } from "./bank-conversion.js";
-import { TalerBankIntegrationHttpClient } from "./bank-integration.js";
-import { TalerRevenueHttpClient } from "./bank-revenue.js";
-import { TalerWireGatewayHttpClient } from "./bank-wire.js";
 import {
   AccessToken,
   PaginationParams,
@@ -66,9 +61,11 @@ import {
   codecForWithdrawalPublicInfo,
 } from "./types.js";
 import {
+  CacheEvictor,
   addLongPollingParam,
   addPaginationParams,
   makeBearerTokenAuthHeader,
+  nullEvictor,
 } from "./utils.js";
 
 export type TalerCoreBankResultByMethod<
@@ -78,25 +75,38 @@ export type TalerCoreBankErrorsByMethod<
   prop extends keyof TalerCoreBankHttpClient,
 > = FailCasesByMethod<TalerCoreBankHttpClient, prop>;
 
-/**
- * Protocol version spoken with the core bank.
- *
- * Endpoint must be ordered in the same way that in the docs
- * Response code (http and taler) must have the same order that in the docs
- * That way is easier to see changes
- *
- * Uses libtool's current:revision:age versioning.
- */
-export class TalerCoreBankHttpClient {
+export enum TalerCoreBankCacheEviction {
+  DELELE_ACCOUNT,
+  CREATE_ACCOUNT,
+  UPDATE_ACCOUNT,
+  UPDATE_PASSWORD,
+  CREATE_TRANSACTION,
+  CONFIRM_WITHDRAWAL,
+  ABORT_WITHDRAWAL,
+  CREATE_WITHDRAWAL,
+  CREATE_CASHOUT,
+}
+  /**
+   * Protocol version spoken with the core bank.
+   *
+   * Endpoint must be ordered in the same way that in the docs
+   * Response code (http and taler) must have the same order that in the docs
+   * That way is easier to see changes
+   *
+   * Uses libtool's current:revision:age versioning.
+   */
+  export class TalerCoreBankHttpClient {
   public readonly PROTOCOL_VERSION = "4:0:0";
 
   httpLib: HttpRequestLibrary;
-
+  cacheEvictor: CacheEvictor<TalerCoreBankCacheEviction>;
   constructor(
     readonly baseUrl: string,
     httpClient?: HttpRequestLibrary,
+    cacheEvictor?: CacheEvictor<TalerCoreBankCacheEviction>,
   ) {
     this.httpLib = httpClient ?? createPlatformHttpLib();
+    this.cacheEvictor = cacheEvictor ?? nullEvictor;
   }
 
   isCompatible(version: string): boolean {
@@ -142,8 +152,10 @@ export class TalerCoreBankHttpClient {
       },
     });
     switch (resp.status) {
-      case HttpStatusCode.Ok:
+      case HttpStatusCode.Ok: {
+        await 
this.cacheEvictor.notifySuccess(TalerCoreBankCacheEviction.CREATE_ACCOUNT)
         return opSuccessFromHttp(resp, codecForRegisterAccountResponse());
+      }
       case HttpStatusCode.BadRequest:
         return opKnownHttpFailure(resp.status, resp);
       case HttpStatusCode.Unauthorized:
@@ -948,47 +960,47 @@ export class TalerCoreBankHttpClient {
    * https://docs.taler.net/core/api-corebank.html#taler-bank-integration-api
    *
    */
-  getIntegrationAPI(): TalerBankIntegrationHttpClient {
-    const url = new URL(`taler-integration/`, this.baseUrl);
-    return new TalerBankIntegrationHttpClient(url.href, this.httpLib);
+  getIntegrationAPI(): string {
+    return new URL(`taler-integration/`, this.baseUrl).href;
+    // return new TalerBankIntegrationHttpClient(url.href, this.httpLib);
   }
 
   /**
    * https://docs.taler.net/core/api-corebank.html#taler-bank-integration-api
    *
    */
-  getWireGatewayAPI(username: string): TalerWireGatewayHttpClient {
-    const url = new URL(
+  getWireGatewayAPI(username: string): string {
+    return new URL(
       `accounts/${username}/taler-wire-gateway/`,
       this.baseUrl,
-    );
-    return new TalerWireGatewayHttpClient(url.href, username, this.httpLib);
+    ).href;
+    // return new TalerWireGatewayHttpClient(url.href, username, this.httpLib);
   }
 
   /**
    * https://docs.taler.net/core/api-corebank.html#taler-bank-integration-api
    *
    */
-  getRevenueAPI(username: string): TalerRevenueHttpClient {
-    const url = new URL(`accounts/${username}/taler-revenue/`, this.baseUrl);
-    return new TalerRevenueHttpClient(url.href, username, this.httpLib);
+  getRevenueAPI(username: string): string {
+    return new URL(`accounts/${username}/taler-revenue/`, this.baseUrl).href;
+    // return new TalerRevenueHttpClient(url.href, username, this.httpLib);
   }
 
   /**
    * 
https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-token
    *
    */
-  getAuthenticationAPI(username: string): TalerAuthenticationHttpClient {
-    const url = new URL(`accounts/${username}/`, this.baseUrl);
-    return new TalerAuthenticationHttpClient(url.href, username, this.httpLib);
+  getAuthenticationAPI(username: string): string {
+    return new URL(`accounts/${username}/`, this.baseUrl).href;
+    // return new TalerAuthenticationHttpClient(url.href, username, 
this.httpLib);
   }
 
   /**
    * 
https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-token
    *
    */
-  getConversionInfoAPI(): TalerBankConversionHttpClient {
-    const url = new URL(`conversion-info/`, this.baseUrl);
-    return new TalerBankConversionHttpClient(url.href, this.httpLib);
+  getConversionInfoAPI(): string {
+    return new URL(`conversion-info/`, this.baseUrl).href;
+    // TalerBankConversionHttpClient
   }
 }
diff --git a/packages/taler-util/src/http-client/utils.ts 
b/packages/taler-util/src/http-client/utils.ts
index 7abedae63..2b8920b66 100644
--- a/packages/taler-util/src/http-client/utils.ts
+++ b/packages/taler-util/src/http-client/utils.ts
@@ -65,3 +65,11 @@ export function addLongPollingParam(url: URL, param?: 
LongPollParams) {
     url.searchParams.set("long_poll_ms", String(param.timeoutMs));
   }
 }
+
+export interface CacheEvictor<T> {
+  notifySuccess: (op: T) => Promise<void>;
+}
+
+export const nullEvictor: CacheEvictor<unknown> = {
+  notifySuccess: () => Promise.resolve()
+}
diff --git a/packages/taler-util/src/index.ts b/packages/taler-util/src/index.ts
index 28909facb..74ef9e8e6 100644
--- a/packages/taler-util/src/index.ts
+++ b/packages/taler-util/src/index.ts
@@ -19,6 +19,7 @@ export * from "./errors.js";
 export { fnutil } from "./fnutils.js";
 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/bank-integration.js";
 export * from "./http-client/bank-revenue.js";

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