gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: fix #8469


From: gnunet
Subject: [taler-wallet-core] branch master updated: fix #8469
Date: Tue, 27 Feb 2024 16:30:30 +0100

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

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

The following commit(s) were added to refs/heads/master by this push:
     new 3a889c177 fix #8469
3a889c177 is described below

commit 3a889c177dd35a114d2c95efd296274cd185ce52
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Tue Feb 27 12:30:24 2024 -0300

    fix #8469
---
 .../src/NavigationBar.tsx                          |   2 +-
 .../src/components/TermsOfService/state.ts         |   7 +-
 .../src/cta/Withdraw/views.tsx                     |  17 +-
 .../src/hooks/useSettings.ts                       |   3 +-
 .../taler-wallet-webextension/src/platform/api.ts  |   6 +-
 .../src/wallet/AddExchange/test.ts                 |   1 +
 .../src/wallet/DestinationSelection/test.ts        |   1 +
 .../src/wallet/DestinationSelection/views.tsx      |   6 +-
 .../src/wallet/DeveloperPage.stories.tsx           |   2 +-
 .../src/wallet/DeveloperPage.tsx                   | 362 +++++++++++++--------
 .../src/wallet/Settings.stories.tsx                |  53 ---
 .../src/wallet/Settings.tsx                        | 193 +++--------
 .../src/wallet/Transaction.tsx                     |   2 +-
 packages/taler-wallet-webextension/src/wxApi.ts    |   8 -
 .../taler-wallet-webextension/src/wxBackend.ts     |  12 -
 .../taler-wallet-webextension/static/wallet.html   |   1 +
 16 files changed, 293 insertions(+), 383 deletions(-)

diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx 
b/packages/taler-wallet-webextension/src/NavigationBar.tsx
index fe4fcc2d9..1837f0508 100644
--- a/packages/taler-wallet-webextension/src/NavigationBar.tsx
+++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx
@@ -259,7 +259,7 @@ export function WalletNavBar({ path }: { path?: 
WalletNavBarOptions }): VNode {
           <Fragment />
         )}
 
-        <EnabledBySettings name="advanceMode">
+        <EnabledBySettings name="advancedMode">
           <a href={Pages.dev} class={path === "dev" ? "active" : ""}>
             <i18n.Translate>Dev tools</i18n.Translate>
           </a>
diff --git 
a/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts 
b/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts
index 0b27c9dcf..88d97af81 100644
--- a/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts
+++ b/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts
@@ -39,7 +39,7 @@ export function useComponentState({ showEvenIfaccepted, 
exchangeUrl, readOnly, c
       WalletApiOperation.GetExchangeTos,
       {
         exchangeBaseUrl: exchangeUrl,
-        acceptedFormat: ["text/html"],
+        acceptedFormat: ["text/xml"],
         acceptLanguage: acceptedLang,
       },
     );
@@ -77,14 +77,9 @@ export function useComponentState({ showEvenIfaccepted, 
exchangeUrl, readOnly, c
     if (accepted) {
       await api.wallet.call(WalletApiOperation.SetExchangeTosAccepted, {
         exchangeBaseUrl: exchangeUrl,
-        etag: state.version,
       });
     } else {
       // mark as not accepted
-      await api.wallet.call(WalletApiOperation.SetExchangeTosAccepted, {
-        exchangeBaseUrl: exchangeUrl,
-        etag: undefined,
-      });
     }
     terms?.retry()
   }
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx 
b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
index 4ceaad010..aade67835 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
@@ -33,6 +33,7 @@ import {
   getAmountWithFee,
 } from "../../wallet/Transaction.js";
 import { State } from "./index.js";
+import { EnabledBySettings } from "../../components/EnabledBySettings.js";
 
 export function FinalStateOperation(state: State.AlreadyCompleted): VNode {
   const { i18n } = useTranslationContext();
@@ -77,13 +78,15 @@ export function SuccessView(state: State.Success): VNode {
               }}
             >
               <i18n.Translate>Exchange</i18n.Translate>
-              <Button onClick={state.doSelectExchange.onClick} variant="text">
-                <SvgIcon
-                  title="Edit"
-                  dangerouslySetInnerHTML={{ __html: editIcon }}
-                  color="black"
-                />
-              </Button>
+              <EnabledBySettings name="showExchangeManagement">
+                <Button onClick={state.doSelectExchange.onClick} 
variant="text">
+                  <SvgIcon
+                    title="Edit"
+                    dangerouslySetInnerHTML={{ __html: editIcon }}
+                    color="black"
+                  />
+                </Button>
+              </EnabledBySettings>
             </div>
           }
           text={
diff --git a/packages/taler-wallet-webextension/src/hooks/useSettings.ts 
b/packages/taler-wallet-webextension/src/hooks/useSettings.ts
index 29449cd59..09fe28888 100644
--- a/packages/taler-wallet-webextension/src/hooks/useSettings.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useSettings.ts
@@ -36,13 +36,14 @@ export const codecForSettings = (): Codec<Settings> =>
     .property("walletAllowHttp", codecForBoolean())
     .property("injectTalerSupport", codecForBoolean())
     .property("autoOpen", codecForBoolean())
-    .property("advanceMode", codecForBoolean())
+    .property("advancedMode", codecForBoolean())
     .property("backup", codecForBoolean())
     .property("langSelector", codecForBoolean())
     .property("showJsonOnError", codecForBoolean())
     .property("extendedAccountTypes", codecForBoolean())
     .property("suspendIndividualTransaction", codecForBoolean())
     .property("showRefeshTransactions", codecForBoolean())
+    .property("showExchangeManagement", codecForBoolean())
     .build("Settings");
 
 const SETTINGS_KEY = buildStorageKey("wallet-settings", codecForSettings());
diff --git a/packages/taler-wallet-webextension/src/platform/api.ts 
b/packages/taler-wallet-webextension/src/platform/api.ts
index 5bc7fd6c5..a16200cc5 100644
--- a/packages/taler-wallet-webextension/src/platform/api.ts
+++ b/packages/taler-wallet-webextension/src/platform/api.ts
@@ -113,25 +113,27 @@ type WebexWalletConfig = {
 export interface Settings extends WebexWalletConfig {
   injectTalerSupport: boolean;
   autoOpen: boolean;
-  advanceMode: boolean;
+  advancedMode: boolean;
   backup: boolean;
   langSelector: boolean;
   showJsonOnError: boolean;
   extendedAccountTypes: boolean;
   showRefeshTransactions: boolean;
   suspendIndividualTransaction: boolean;
+  showExchangeManagement: boolean;
 }
 
 export const defaultSettings: Settings = {
   injectTalerSupport: false,
   autoOpen: true,
-  advanceMode: false,
+  advancedMode: false,
   backup: false,
   langSelector: false,
   showRefeshTransactions: false,
   suspendIndividualTransaction: false,
   showJsonOnError: false,
   extendedAccountTypes: false,
+  showExchangeManagement: false,
   walletAllowHttp: false,
 };
 
diff --git a/packages/taler-wallet-webextension/src/wallet/AddExchange/test.ts 
b/packages/taler-wallet-webextension/src/wallet/AddExchange/test.ts
index 60d5b274c..aa6384df2 100644
--- a/packages/taler-wallet-webextension/src/wallet/AddExchange/test.ts
+++ b/packages/taler-wallet-webextension/src/wallet/AddExchange/test.ts
@@ -49,6 +49,7 @@ describe("AddExchange states", () => {
             exchangeBaseUrl: "http://exchange.local/";,
             ageRestrictionOptions: [],
             scopeInfo: undefined,
+            masterPub: "123qwe123",
             currency: "ARS",
             exchangeEntryStatus: ExchangeEntryStatus.Ephemeral,
             tosStatus: ExchangeTosStatus.Pending,
diff --git 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts
index 3082ae7a4..0a99e6af9 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts
@@ -36,6 +36,7 @@ import { useComponentState } from "./state.js";
 const exchangeArs: ExchangeListItem = {
   currency: "ARS",
   exchangeBaseUrl: "http://";,
+  masterPub:"123qwe123",
   scopeInfo: undefined,
   tosStatus: ExchangeTosStatus.Accepted,
   exchangeEntryStatus: ExchangeEntryStatus.Used,
diff --git 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
index f8e2c6707..c40a3a64c 100644
--- 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
+++ 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
@@ -14,6 +14,7 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
+import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { styled } from "@linaria/react";
 import { Fragment, h, VNode } from "preact";
 import { AmountField } from "../../components/AmountField.js";
@@ -25,7 +26,6 @@ import {
   LinkPrimary,
   SvgIcon,
 } from "../../components/styled/index.js";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Button } from "../../mui/Button.js";
 import { Grid } from "../../mui/Grid.js";
 import { Paper } from "../../mui/Paper.js";
@@ -34,8 +34,6 @@ import arrowIcon from "../../svg/chevron-down.inline.svg";
 import bankIcon from "../../svg/ri-bank-line.inline.svg";
 import { assertUnreachable } from "../../utils/index.js";
 import { Contact, State } from "./index.js";
-import { useEffect } from "preact/hooks";
-import { Checkbox } from "../../components/Checkbox.js";
 
 export function SelectCurrencyView({
   currencies,
@@ -303,7 +301,7 @@ export function ReadySendView({
           required
           handler={amountHandler}
         />
-        <EnabledBySettings name="advanceMode">
+        <EnabledBySettings name="advancedMode">
           <Button onClick={selectMax.onClick}>
             <i18n.Translate>Send all</i18n.Translate>
           </Button>
diff --git 
a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.stories.tsx
index c2c794e89..e7c9111fd 100644
--- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.stories.tsx
@@ -21,7 +21,7 @@
 
 import { AbsoluteTime } from "@gnu-taler/taler-util";
 import * as tests from "@gnu-taler/web-util/testing";
-import { View as TestedComponent } from "./DeveloperPage.js";
+import { DeveloperPage as TestedComponent } from "./DeveloperPage.js";
 
 export default {
   title: "developer",
diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx 
b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
index 0db7a07eb..d19fef155 100644
--- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
@@ -20,8 +20,12 @@ import {
   CoinDumpJson,
   CoinStatus,
   ExchangeListItem,
+  ExchangeTosStatus,
   LogLevel,
   NotificationType,
+  ScopeType,
+  parseWithdrawUri,
+  stringifyWithdrawExchange,
 } from "@gnu-taler/taler-util";
 import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
@@ -31,7 +35,7 @@ import { useEffect, useRef, useState } from "preact/hooks";
 import { Checkbox } from "../components/Checkbox.js";
 import { SelectList } from "../components/SelectList.js";
 import { Time } from "../components/Time.js";
-import { NotifyUpdateFadeOut } from "../components/styled/index.js";
+import { DestructiveText, LinkPrimary, NotifyUpdateFadeOut, SubTitle, 
SuccessText, WarningText } from "../components/styled/index.js";
 import { useAlertContext } from "../context/alert.js";
 import { useBackendContext } from "../context/backend.js";
 import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
@@ -40,50 +44,8 @@ import { Button } from "../mui/Button.js";
 import { Grid } from "../mui/Grid.js";
 import { Paper } from "../mui/Paper.js";
 import { TextField } from "../mui/TextField.js";
-
-export function DeveloperPage(): VNode {
-  const listenAllEvents = Array.from<NotificationType>({ length: 1 });
-
-  const api = useBackendContext();
-
-  const response = useAsyncAsHook(async () => {
-    const op = await api.wallet.call(
-      WalletApiOperation.GetPendingOperations,
-      {},
-    );
-    const c = await api.wallet.call(WalletApiOperation.DumpCoins, {});
-    const ex = await api.wallet.call(WalletApiOperation.ListExchanges, {});
-    return {
-      operations: op.pendingOperations,
-      coins: c.coins,
-      exchanges: ex.exchanges,
-    };
-  });
-
-  useEffect(() => {
-    return api.listener.onUpdateNotification(listenAllEvents, response?.retry);
-  });
-
-  const nonResponse = { operations: [], coins: [], exchanges: [] };
-  const { operations, coins, exchanges } =
-    response === undefined
-      ? nonResponse
-      : response.hasError
-        ? nonResponse
-        : response.response;
-
-  return (
-    <View
-      operations={operations}
-      coins={coins}
-      exchanges={exchanges}
-      onDownloadDatabase={async () => {
-        const db = await api.wallet.call(WalletApiOperation.ExportDb, {});
-        return JSON.stringify(db);
-      }}
-    />
-  );
-}
+import { Pages } from "../NavigationBar.js";
+import { CoinInfo } from "@gnu-taler/taler-wallet-core/dbless";
 
 type CoinsInfo = CoinDumpJson["coins"];
 type CalculatedCoinfInfo = {
@@ -103,23 +65,20 @@ type SplitedCoinInfo = {
 
 export interface Props {
   // FIXME: Pending operations don't exist anymore.
-  operations: any[];
-  coins: CoinsInfo;
-  exchanges: ExchangeListItem[];
-  onDownloadDatabase: () => Promise<string>;
 }
 
 function hashObjectId(o: any): string {
   return JSON.stringify(o);
 }
 
-export function View({ operations, coins, onDownloadDatabase }: Props): VNode {
+export function DeveloperPage({ }: Props): VNode {
   const { i18n } = useTranslationContext();
   const [downloadedDatabase, setDownloadedDatabase] = useState<
     { time: Date; content: string } | undefined
   >(undefined);
   async function onExportDatabase(): Promise<void> {
-    const content = await onDownloadDatabase();
+    const db = await api.wallet.call(WalletApiOperation.ExportDb, {});
+    const content = JSON.stringify(db);
     setDownloadedDatabase({
       time: new Date(),
       content,
@@ -136,10 +95,28 @@ export function View({ operations, coins, 
onDownloadDatabase }: Props): VNode {
   const [settings, updateSettings] = useSettings();
   const { safely } = useAlertContext();
 
-  const hook = useAsyncAsHook(() =>
-    api.wallet.call(WalletApiOperation.ListExchanges, {}),
-  );
+  // const hook = useAsyncAsHook(() =>
+  //   api.wallet.call(WalletApiOperation.ListExchanges, {}),
+  // );
+  const listenAllEvents = Array.from<NotificationType>({ length: 1 });
+
+  const hook = useAsyncAsHook(async () => {
+    const list = await api.wallet.call(WalletApiOperation.ListExchanges, {});
+    const version = await api.wallet.call(WalletApiOperation.GetVersion, {});
+    const operations: any[] = await api.wallet.call(
+      WalletApiOperation.GetPendingOperations,
+      {},
+    );
+    const coins = await api.wallet.call(WalletApiOperation.DumpCoins, {});
+    return { exchanges: list.exchanges, version, coins, operations };
+  });
   const exchangeList = hook && !hook.hasError ? hook.response.exchanges : [];
+  const coins = hook && !hook.hasError ? hook.response.coins.coins : [];
+  const operations = hook && !hook.hasError ? hook.response.operations : [];
+
+  useEffect(() => {
+    return api.listener.onUpdateNotification(listenAllEvents, hook?.retry);
+  });
 
   const currencies: { [ex: string]: string } = {};
   const money_by_exchange = coins.reduce(
@@ -202,30 +179,6 @@ export function View({ operations, coins, 
onDownloadDatabase }: Props): VNode {
             <i18n.Translate>run gc</i18n.Translate>
           </Button>
         </Grid>
-        <Grid item>
-          <Button
-            variant="contained"
-            onClick={() => {
-              return api.background.call("sum", [1, 2, 3]).then((r) => {
-                console.log("SUM", r);
-              });
-            }}
-          >
-            <i18n.Translate>sum 123</i18n.Translate>
-          </Button>
-        </Grid>
-        <Grid item>
-          <Button
-            variant="contained"
-            onClick={() => {
-              return api.background.call("freeze", 4000).then(() => {
-                console.log("WAIT");
-              });
-            }}
-          >
-            <i18n.Translate>freeze 4000</i18n.Translate>
-          </Button>
-        </Grid>
         <Grid item>
           <Button
             variant="contained"
@@ -256,64 +209,6 @@ export function View({ operations, coins, 
onDownloadDatabase }: Props): VNode {
             <i18n.Translate>export database</i18n.Translate>
           </Button>
         </Grid>
-        <Grid item>
-          <Button
-            variant="contained"
-            onClick={async () => {
-              navigator.registerProtocolHandler(
-                "taler",
-                
`${window.location.origin}/static/wallet.html#/cta/withdraw?talerWithdrawUri=%s`,
-              );
-            }}
-          >
-            <i18n.Translate>Register taler:// handler</i18n.Translate>
-          </Button>
-        </Grid>
-        <Grid item>
-          <Button
-            variant="contained"
-            onClick={async () => {
-              const n = navigator as any;
-              if ("unregisterProtocolHandler" in n) {
-                n.unregisterProtocolHandler(
-                  "taler",
-                  
`${window.location.origin}/static/wallet.html#/cta/withdraw?talerWithdrawUri=%s`,
-                );
-              }
-            }}
-          >
-            <i18n.Translate>Remove taler:// handler</i18n.Translate>
-          </Button>
-        </Grid>{" "}
-        <Grid item>
-          <Button
-            variant="contained"
-            onClick={async () => {
-              navigator.registerProtocolHandler(
-                "ext+taler",
-                
`${window.location.origin}/static/wallet.html#/cta/withdraw?talerWithdrawUri=%s`,
-              );
-            }}
-          >
-            <i18n.Translate>Register ext+taler:// handler</i18n.Translate>
-          </Button>
-        </Grid>
-        <Grid item>
-          <Button
-            variant="contained"
-            onClick={async () => {
-              const n = navigator as any;
-              if ("unregisterProtocolHandler" in n) {
-                n.unregisterProtocolHandler(
-                  "ext+taler",
-                  
`${window.location.origin}/static/wallet.html#/cta/withdraw?talerWithdrawUri=%s`,
-                );
-              }
-            }}
-          >
-            <i18n.Translate>Remove ext+taler:// handler</i18n.Translate>
-          </Button>
-        </Grid>
         <Grid item>
           <Button
             variant="contained"
@@ -359,6 +254,201 @@ export function View({ operations, coins, 
onDownloadDatabase }: Props): VNode {
         })}
       />
 
+
+      <SubTitle>
+        <i18n.Translate>Exchange Entries</i18n.Translate>
+      </SubTitle>
+      {!exchangeList || !exchangeList.length ? (
+        <div>
+          <i18n.Translate>No exchange yet</i18n.Translate>
+        </div>
+      ) : (
+        <Fragment>
+          <table>
+            <thead>
+              <tr>
+                <th>
+                  <i18n.Translate>Currency</i18n.Translate>
+                </th>
+                <th>
+                  <i18n.Translate>URL</i18n.Translate>
+                </th>
+                <th>
+                  <i18n.Translate>Status</i18n.Translate>
+                </th>
+                <th>
+                  <i18n.Translate>Terms of Service</i18n.Translate>
+                </th>
+                <th>
+                  <i18n.Translate>Last Update</i18n.Translate>
+                </th>
+                <th>
+                  <i18n.Translate>Actions</i18n.Translate>
+                </th>
+              </tr>
+            </thead>
+            <tbody>
+              {exchangeList.map((e, idx) => {
+                function TosStatus(): VNode {
+                  switch (e.tosStatus) {
+                    case ExchangeTosStatus.Accepted:
+                      return (
+                        <SuccessText>
+                          <i18n.Translate>ok</i18n.Translate>
+                        </SuccessText>
+                      );
+                    case ExchangeTosStatus.Pending:
+                      return (
+                        <WarningText>
+                          <i18n.Translate>pending</i18n.Translate>
+                        </WarningText>
+                      );
+                    case ExchangeTosStatus.Proposed:
+                      return <i18n.Translate>proposed</i18n.Translate>;
+                    default:
+                      return (
+                        <DestructiveText>
+                          <i18n.Translate>
+                            unknown (exchange status should be updated)
+                          </i18n.Translate>
+                        </DestructiveText>
+                      );
+                  }
+                }
+                const uri = !e.masterPub ? undefined : 
stringifyWithdrawExchange({
+                  exchangeBaseUrl: e.exchangeBaseUrl,
+                  exchangePub: e.masterPub,
+                });
+                return (
+                  <tr key={idx}>
+                    <td>
+                      <a href={!uri? undefined: Pages.defaultCta({ uri })}>
+                        {e.scopeInfo ? `${e.scopeInfo.currency} 
(${e.scopeInfo.type === ScopeType.Global ? "global" : "regional"})` : 
e.currency}
+                      </a>
+                    </td>
+                    <td>
+                      <a href={new URL(`/keys`, e.exchangeBaseUrl).href} 
target="_blank">{e.exchangeBaseUrl}</a>
+                    </td>
+                    <td>
+                      {e.exchangeEntryStatus} / {e.exchangeUpdateStatus}
+                    </td>
+                    <td>
+                      <TosStatus />
+                    </td>
+                    <td>
+                      {e.lastUpdateTimestamp
+                        ? AbsoluteTime.toIsoString(
+                          AbsoluteTime.fromPreciseTimestamp(
+                            e.lastUpdateTimestamp,
+                          ),
+                        )
+                        : "never"}
+                    </td>
+                    <td>
+                      <button
+                        onClick={() => {
+                          api.wallet.call(
+                            WalletApiOperation.UpdateExchangeEntry,
+                            {
+                              exchangeBaseUrl: e.exchangeBaseUrl,
+                              force: true,
+                            },
+                          );
+                        }}
+                      >
+                        Reload
+                      </button>
+                      <button
+                        onClick={() => {
+                          api.wallet.call(
+                            WalletApiOperation.DeleteExchange,
+                            {
+                              exchangeBaseUrl: e.exchangeBaseUrl,
+                            },
+                          );
+                        }}
+                      >
+                        Delete
+                      </button>
+                      <button
+                        onClick={() => {
+                          api.wallet.call(
+                            WalletApiOperation.DeleteExchange,
+                            {
+                              exchangeBaseUrl: e.exchangeBaseUrl,
+                              purge: true,
+                            },
+                          );
+                        }}
+                      >
+                        Purge
+                      </button>
+                      {e.scopeInfo && e.masterPub && e.currency ?
+                        (e.scopeInfo.type === ScopeType.Global ?
+                          <button
+                            onClick={() => {
+                              api.wallet.call(
+                                
WalletApiOperation.RemoveGlobalCurrencyExchange,
+                                {
+                                  exchangeBaseUrl: e.exchangeBaseUrl,
+                                  currency: e.currency!,
+                                  exchangeMasterPub: e.masterPub!,
+                                },
+                              );
+                            }}
+                          >
+
+                            Make regional
+                          </button>
+                          : e.scopeInfo.type === ScopeType.Auditor ?
+                            undefined
+
+                            : e.scopeInfo.type === ScopeType.Exchange ?
+                              <button
+                                onClick={() => {
+                                  api.wallet.call(
+                                    
WalletApiOperation.AddGlobalCurrencyExchange,
+                                    {
+                                      exchangeBaseUrl: e.exchangeBaseUrl,
+                                      currency: e.currency!,
+                                      exchangeMasterPub: e.masterPub!,
+                                    },
+                                  );
+                                }}
+                              >
+
+                                Make global
+                              </button>
+                              : undefined) : undefined
+                      }
+                      <button
+                        onClick={() => {
+                          api.wallet.call(
+                            WalletApiOperation.SetExchangeTosForgotten,
+                            {
+                              exchangeBaseUrl: e.exchangeBaseUrl,
+                            },
+                          );
+                        }}
+                      >
+                        Forget ToS
+                      </button>
+                    </td>
+                  </tr>
+                );
+              })}
+            </tbody>
+          </table>
+        </Fragment>
+      )}
+      <div style={{ display: "flex", justifyContent: "space-between" }}>
+        <div />
+        <LinkPrimary href={Pages.settingsExchangeAdd({})}>
+          <i18n.Translate>Add an exchange</i18n.Translate>
+        </LinkPrimary>
+      </div>
+
+
       <Paper style={{ padding: 10, margin: 10 }}>
         <h3>Logging</h3>
         <div>
diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx
index a5d6972de..cd43c4526 100644
--- a/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx
@@ -75,19 +75,6 @@ export const WithOneExchange = 
tests.createExample(TestedComponent, {
   autoOpenToggle: { value: false, button: {} },
   langToggle: { value: false, button: {} },
   setDeviceName: () => Promise.resolve(),
-  knownExchanges: [
-    {
-      currency: "USD",
-      exchangeBaseUrl: "http://exchange.taler";,
-      tos: {
-        currentVersion: "1",
-        acceptedVersion: "1",
-        content: "content of tos",
-        contentType: "text/plain",
-      },
-      paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"],
-    } as any, //TODO: complete with auditors, wireInfo and denominations
-  ],
   ...version,
 });
 
@@ -99,46 +86,6 @@ export const WithExchangeInDifferentState = 
tests.createExample(
     autoOpenToggle: { value: false, button: {} },
     langToggle: { value: false, button: {} },
     setDeviceName: () => Promise.resolve(),
-    knownExchanges: [
-      {
-        currency: "USD",
-        exchangeBaseUrl: "http://exchange1.taler";,
-        tos: {
-          currentVersion: "1",
-          acceptedVersion: "1",
-          content: "content of tos",
-          contentType: "text/plain",
-        },
-        paytoUris: [
-          "payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator",
-        ],
-      },
-      {
-        currency: "USD",
-        exchangeBaseUrl: "http://exchange2.taler";,
-        tos: {
-          currentVersion: "2",
-          acceptedVersion: "1",
-          content: "content of tos",
-          contentType: "text/plain",
-        },
-        paytoUris: [
-          "payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator",
-        ],
-      } as any, //TODO: complete with auditors, wireInfo and denominations
-      {
-        currency: "USD",
-        exchangeBaseUrl: "http://exchange3.taler";,
-        tos: {
-          currentVersion: "1",
-          content: "content of tos",
-          contentType: "text/plain",
-        },
-        paytoUris: [
-          "payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator",
-        ],
-      },
-    ],
     ...version,
   },
 );
diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx 
b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
index ec716cb87..b8fc14469 100644
--- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
@@ -16,9 +16,11 @@
 
 import {
   AbsoluteTime,
+  ExchangeDetailedResponse,
   ExchangeListItem,
   ExchangeTosStatus,
   LibtoolVersion,
+  ScopeType,
   TranslatedString,
   WalletCoreVersion,
 } from "@gnu-taler/taler-util";
@@ -58,19 +60,15 @@ export function SettingsPage(): VNode {
   const webex = platform.getWalletWebExVersion();
   const api = useBackendContext();
 
-  const exchangesHook = useAsyncAsHook(async () => {
-    const list = await api.wallet.call(WalletApiOperation.ListExchanges, {});
+  const hook = useAsyncAsHook(async () => {
     const version = await api.wallet.call(WalletApiOperation.GetVersion, {});
-    return { exchanges: list.exchanges, version };
+    return { version };
   });
-  const { exchanges, version } =
-    !exchangesHook || exchangesHook.hasError
-      ? { exchanges: [], version: undefined }
-      : exchangesHook.response;
+
+  const version = hook && !hook.hasError ? hook.response.version : undefined
 
   return (
     <SettingsView
-      knownExchanges={exchanges}
       deviceName={name}
       setDeviceName={update}
       autoOpenToggle={{
@@ -82,10 +80,10 @@ export function SettingsPage(): VNode {
         },
       }}
       advanceToggle={{
-        value: settings.advanceMode,
+        value: settings.advancedMode,
         button: {
           onClick: safely("update advance mode", async () => {
-            updateSettings("advanceMode", !settings.advanceMode);
+            updateSettings("advancedMode", !settings.advancedMode);
           }),
         },
       }}
@@ -112,7 +110,6 @@ export interface ViewProps {
   autoOpenToggle: ToggleHandler;
   advanceToggle: ToggleHandler;
   langToggle: ToggleHandler;
-  knownExchanges: Array<ExchangeListItem>;
   coreVersion: WalletCoreVersion | undefined;
   webexVersion: {
     version: string;
@@ -121,7 +118,6 @@ export interface ViewProps {
 }
 
 export function SettingsView({
-  knownExchanges,
   autoOpenToggle,
   advanceToggle,
   langToggle,
@@ -135,143 +131,6 @@ export function SettingsView({
   return (
     <Fragment>
       <section>
-        <SubTitle>
-          <i18n.Translate>Exchange Entries</i18n.Translate>
-        </SubTitle>
-        {!knownExchanges || !knownExchanges.length ? (
-          <div>
-            <i18n.Translate>No exchange yet</i18n.Translate>
-          </div>
-        ) : (
-          <Fragment>
-            <table>
-              <thead>
-                <tr>
-                  <th>
-                    <i18n.Translate>Currency</i18n.Translate>
-                  </th>
-                  <th>
-                    <i18n.Translate>URL</i18n.Translate>
-                  </th>
-                  <th>
-                    <i18n.Translate>Status</i18n.Translate>
-                  </th>
-                  <th>
-                    <i18n.Translate>Terms of Service</i18n.Translate>
-                  </th>
-                  <th>
-                    <i18n.Translate>Last Update</i18n.Translate>
-                  </th>
-                  <th>
-                    <i18n.Translate>Actions</i18n.Translate>
-                  </th>
-                </tr>
-              </thead>
-              <tbody>
-                {knownExchanges.map((e, idx) => {
-                  function TosStatus(): VNode {
-                    switch (e.tosStatus) {
-                      case ExchangeTosStatus.Accepted:
-                        return (
-                          <SuccessText>
-                            <i18n.Translate>ok</i18n.Translate>
-                          </SuccessText>
-                        );
-                      case ExchangeTosStatus.Pending:
-                        return (
-                          <WarningText>
-                            <i18n.Translate>pending</i18n.Translate>
-                          </WarningText>
-                        );
-                      case ExchangeTosStatus.Proposed:
-                        return <i18n.Translate>proposed</i18n.Translate>;
-                      default:
-                        return (
-                          <DestructiveText>
-                            <i18n.Translate>
-                              unknown (exchange status should be updated)
-                            </i18n.Translate>
-                          </DestructiveText>
-                        );
-                    }
-                  }
-                  return (
-                    <tr key={idx}>
-                      <td>{e.currency}</td>
-                      <td>
-                        <a href={e.exchangeBaseUrl}>{e.exchangeBaseUrl}</a>
-                      </td>
-                      <td>
-                        {e.exchangeEntryStatus} / {e.exchangeUpdateStatus}
-                      </td>
-                      <td>
-                        <TosStatus />
-                      </td>
-                      <td>
-                        {e.lastUpdateTimestamp
-                          ? AbsoluteTime.toIsoString(
-                              AbsoluteTime.fromPreciseTimestamp(
-                                e.lastUpdateTimestamp,
-                              ),
-                            )
-                          : "never"}
-                      </td>
-                      <td>
-                        <button
-                          onClick={() => {
-                            console.log(`force-updating ${e.exchangeBaseUrl}`);
-                            api.wallet.call(
-                              WalletApiOperation.UpdateExchangeEntry,
-                              {
-                                exchangeBaseUrl: e.exchangeBaseUrl,
-                                force: true,
-                              },
-                            );
-                          }}
-                        >
-                          Reload
-                        </button>
-                      </td>
-                    </tr>
-                  );
-                })}
-              </tbody>
-            </table>
-          </Fragment>
-        )}
-        <div style={{ display: "flex", justifyContent: "space-between" }}>
-          <div />
-          <LinkPrimary href={Pages.settingsExchangeAdd({})}>
-            <i18n.Translate>Add an exchange</i18n.Translate>
-          </LinkPrimary>
-        </div>
-        <SubTitle>
-          <i18n.Translate>Advanced mode</i18n.Translate>
-        </SubTitle>
-        <Checkbox
-          label={i18n.str`Enable advanced mode`}
-          name="devMode"
-          description={i18n.str`Show more information and options in the UI`}
-          enabled={advanceToggle.value!}
-          onToggle={advanceToggle.button.onClick!}
-        />
-        <EnabledBySettings name="advanceMode">
-          <AdvanceSettings />
-        </EnabledBySettings>
-        <EnabledBySettings name="langSelector">
-          <SubTitle>
-            <i18n.Translate>Display</i18n.Translate>
-          </SubTitle>
-          <Input>
-            <SelectList
-              label={<i18n.Translate>Current Language</i18n.Translate>}
-              list={supportedLang}
-              name="lang"
-              value={lang}
-              onChange={(v) => changeLanguage(v)}
-            />
-          </Input>
-        </EnabledBySettings>
         <SubTitle>
           <i18n.Translate>Navigator</i18n.Translate>
         </SubTitle>
@@ -286,6 +145,7 @@ export function SettingsView({
           enabled={autoOpenToggle.value!}
           onToggle={autoOpenToggle.button.onClick!}
         />
+
         <SubTitle>
           <i18n.Translate>Version Info</i18n.Translate>
         </SubTitle>
@@ -294,7 +154,7 @@ export function SettingsView({
           text={
             <span>
               {webexVersion.version}{" "}
-              <EnabledBySettings name="advanceMode">
+              <EnabledBySettings name="advancedMode">
                 {webexVersion.hash}
               </EnabledBySettings>
             </span>
@@ -313,7 +173,7 @@ export function SettingsView({
                 </i18n.Translate>
               </WarningBox>
             )}
-            <EnabledBySettings name="advanceMode">
+            <EnabledBySettings name="advancedMode">
               <Part
                 title={i18n.str`Exchange compatibility`}
                 text={<span>{coreVersion.exchange}</span>}
@@ -333,6 +193,33 @@ export function SettingsView({
             </EnabledBySettings>
           </Fragment>
         )}
+        <SubTitle>
+          <i18n.Translate>Settings</i18n.Translate>
+        </SubTitle>
+        <Checkbox
+          label={i18n.str`Enable developer mode`}
+          name="devMode"
+          description={i18n.str`Show more information and options in the UI`}
+          enabled={advanceToggle.value!}
+          onToggle={advanceToggle.button.onClick!}
+        />
+        <EnabledBySettings name="advancedMode">
+          <AdvanceSettings />
+        </EnabledBySettings>
+        <EnabledBySettings name="langSelector">
+          <SubTitle>
+            <i18n.Translate>Display</i18n.Translate>
+          </SubTitle>
+          <Input>
+            <SelectList
+              label={<i18n.Translate>Current Language</i18n.Translate>}
+              list={supportedLang}
+              name="lang"
+              value={lang}
+              onChange={(v) => changeLanguage(v)}
+            />
+          </Input>
+        </EnabledBySettings>
       </section>
     </Fragment>
   );
@@ -374,6 +261,10 @@ function AdvanceSettings(): VNode {
       label: i18n.str`Lang selector`,
       description: i18n.str`Allows to manually change the language of the UI. 
Otherwise it will be automatically selected by your browser configuration.`,
     },
+    showExchangeManagement: {
+      label: i18n.str`Edit exchange management`,
+      description: i18n.str`Allows to see the list of exchange, remove, add 
and switch before withdrawal.`,
+    },
   };
   return (
     <Fragment>
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx 
b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
index 65fc90f44..65ba6cc85 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
@@ -1960,7 +1960,7 @@ function ShowWithdrawalDetailForBankIntegrated({
   const raw = Amounts.parseOrThrow(transaction.amountRaw);
   return (
     <Fragment>
-      <EnabledBySettings name="advanceMode">
+      <EnabledBySettings name="advancedMode">
         <a
           href="#"
           onClick={(e) => {
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts 
b/packages/taler-wallet-webextension/src/wxApi.ts
index d989c9662..b73b12263 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -60,14 +60,6 @@ export interface ExtendedPermissionsResponse {
 }
 
 export interface BackgroundOperations {
-  freeze: {
-    request: number;
-    response: void;
-  };
-  sum: {
-    request: number[];
-    response: number;
-  };
   resetDb: {
     request: void;
     response: void;
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts 
b/packages/taler-wallet-webextension/src/wxBackend.ts
index 70db60eca..051048e81 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -111,16 +111,6 @@ async function runGarbageCollector(): Promise<void> {
   logger.info("imported");
 }
 
-function freeze(time: number): Promise<void> {
-  return new Promise((res, rej) => {
-    setTimeout(res, time);
-  });
-}
-
-async function sum(ns: Array<number>): Promise<number> {
-  return ns.reduce((prev, cur) => prev + cur, 0);
-}
-
 const extensionHandlers: ExtensionHandlerType = {
   isAutoOpenEnabled,
   isDomainTrusted,
@@ -137,8 +127,6 @@ async function isDomainTrusted(): Promise<boolean> {
 }
 
 const backendHandlers: BackendHandlerType = {
-  freeze,
-  sum,
   resetDb,
   runGarbageCollector,
   setLoggingLevel,
diff --git a/packages/taler-wallet-webextension/static/wallet.html 
b/packages/taler-wallet-webextension/static/wallet.html
index c8baa7e4d..3025901d8 100644
--- a/packages/taler-wallet-webextension/static/wallet.html
+++ b/packages/taler-wallet-webextension/static/wallet.html
@@ -4,6 +4,7 @@
 <head>
   <title>GNU Taler Wallet - WebExtension</title>
   <meta charset="utf-8" />
+  <meta name="taler-support" content="uri,api" /> 
   <link rel="stylesheet" type="text/css" href="/dist/walletEntryPoint.css" />
   <link rel="stylesheet" type="text/css" href="/static/font/import.css" />
   <link rel="icon"

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