summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-11-22 13:33:44 -0300
committerSebastian <sebasjm@gmail.com>2023-11-22 15:20:28 -0300
commit33c0267b37eecf44dc9f04e124eb44d27cba700c (patch)
tree9d5549dbb5a415b44005ab05711fc66c4643cbc9 /packages
parent5eec408d9fb5e8c2375937166997ef8267a4053c (diff)
downloadwallet-core-33c0267b37eecf44dc9f04e124eb44d27cba700c.tar.gz
wallet-core-33c0267b37eecf44dc9f04e124eb44d27cba700c.tar.bz2
wallet-core-33c0267b37eecf44dc9f04e124eb44d27cba700c.zip
settings and preferences, getting conversion info
Diffstat (limited to 'packages')
-rwxr-xr-xpackages/demobank-ui/dev.mjs4
-rw-r--r--packages/demobank-ui/src/Routing.tsx10
-rw-r--r--packages/demobank-ui/src/bank-ui-settings.js19
-rw-r--r--packages/demobank-ui/src/components/app.tsx52
-rw-r--r--packages/demobank-ui/src/context/settings.ts44
-rw-r--r--packages/demobank-ui/src/hooks/backend.ts1
-rw-r--r--packages/demobank-ui/src/hooks/circuit.ts63
-rw-r--r--packages/demobank-ui/src/hooks/preferences.ts (renamed from packages/demobank-ui/src/hooks/settings.ts)30
-rw-r--r--packages/demobank-ui/src/index.html2
-rw-r--r--packages/demobank-ui/src/pages/AccountPage/views.tsx4
-rw-r--r--packages/demobank-ui/src/pages/BankFrame.tsx23
-rw-r--r--packages/demobank-ui/src/pages/LoginForm.tsx13
-rw-r--r--packages/demobank-ui/src/pages/OperationState/state.ts4
-rw-r--r--packages/demobank-ui/src/pages/OperationState/views.tsx6
-rw-r--r--packages/demobank-ui/src/pages/PaymentOptions.tsx4
-rw-r--r--packages/demobank-ui/src/pages/RegistrationPage.tsx17
-rw-r--r--packages/demobank-ui/src/pages/WalletWithdrawForm.tsx6
-rw-r--r--packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx4
-rw-r--r--packages/demobank-ui/src/pages/WithdrawalOperationPage.tsx4
-rw-r--r--packages/demobank-ui/src/pages/business/CreateCashout.tsx32
-rw-r--r--packages/demobank-ui/src/pages/rnd.ts2
-rw-r--r--packages/demobank-ui/src/settings.json12
-rw-r--r--packages/demobank-ui/src/settings.ts33
-rw-r--r--packages/taler-util/src/http-client/types.ts85
-rw-r--r--packages/web-util/src/components/Header.tsx7
25 files changed, 251 insertions, 230 deletions
diff --git a/packages/demobank-ui/dev.mjs b/packages/demobank-ui/dev.mjs
index 8b04155f4..c5ea318e7 100755
--- a/packages/demobank-ui/dev.mjs
+++ b/packages/demobank-ui/dev.mjs
@@ -18,13 +18,13 @@
import { serve } from "@gnu-taler/web-util/node";
import { initializeDev } from "@gnu-taler/web-util/build";
-const devEntryPoints = ["src/stories.tsx", "src/index.tsx", "src/bank-ui-settings.js"];
+const devEntryPoints = ["src/stories.tsx", "src/index.tsx"];
const build = initializeDev({
type: "development",
source: {
js: devEntryPoints,
- assets: [{ base: "src", files: ["src/index.html"] }],
+ assets: [{ base: "src", files: ["src/index.html", "src/settings.json"] }],
},
destination: "./dist/dev",
public: "/app",
diff --git a/packages/demobank-ui/src/Routing.tsx b/packages/demobank-ui/src/Routing.tsx
index d797a837d..733d55a0f 100644
--- a/packages/demobank-ui/src/Routing.tsx
+++ b/packages/demobank-ui/src/Routing.tsx
@@ -19,6 +19,7 @@ import { createHashHistory } from "history";
import { Fragment, VNode, h } from "preact";
import { Route, Router, route } from "preact-router";
import { useEffect } from "preact/hooks";
+
import { useBackendState } from "./hooks/backend.js";
import { BankFrame } from "./pages/BankFrame.js";
import { WithdrawalOperationPage } from "./pages/WithdrawalOperationPage.js";
@@ -27,7 +28,6 @@ import { PublicHistoriesPage } from "./pages/PublicHistoriesPage.js";
import { RegistrationPage } from "./pages/RegistrationPage.js";
import { AdminHome } from "./pages/admin/AdminHome.js";
import { CreateCashout } from "./pages/business/CreateCashout.js";
-import { bankUiSettings } from "./settings.js";
import { ShowAccountDetails } from "./pages/account/ShowAccountDetails.js";
import { UpdateAccountPassword } from "./pages/account/UpdateAccountPassword.js";
import { RemoveAccount } from "./pages/admin/RemoveAccount.js";
@@ -36,10 +36,14 @@ import { CashoutListForAccount } from "./pages/account/CashoutListForAccount.js"
import { ShowCashoutDetails } from "./pages/business/ShowCashoutDetails.js";
import { WireTransfer } from "./pages/WireTransfer.js";
import { AccountPage } from "./pages/AccountPage/index.js";
+import { useSettingsContext } from "./context/settings.js";
+import { useBankCoreApiContext } from "./context/config.js";
export function Routing(): VNode {
const history = createHashHistory();
const backend = useBackendState();
+ const settings = useSettingsContext();
+ const {config} = useBankCoreApiContext();
const { i18n } = useTranslationContext();
if (backend.state.status === "loggedOut") {
@@ -50,7 +54,7 @@ export function Routing(): VNode {
component={() => (
<Fragment>
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
- <h2 class="text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">{i18n.str`Welcome to ${bankUiSettings.bankName}!`}</h2>
+ <h2 class="text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">{i18n.str`Welcome to ${settings.bankName}!`}</h2>
</div>
<LoginForm
@@ -76,7 +80,7 @@ export function Routing(): VNode {
/>
)}
/>
- {bankUiSettings.allowRegistrations &&
+ {config.allow_registrations &&
<Route
path="/register"
component={() => (
diff --git a/packages/demobank-ui/src/bank-ui-settings.js b/packages/demobank-ui/src/bank-ui-settings.js
deleted file mode 100644
index 397fa28c0..000000000
--- a/packages/demobank-ui/src/bank-ui-settings.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Values for development environment
-
-/**
- * Global settings for the bank UI.
- */
-globalThis.talerBankSettings = {
- backendBaseURL: "http://bank.taler.test:1180/",
- allowRegistrations: true,
- showDemoNav: true,
- simplePasswordForRandomAccounts: true,
- allowRandomAccountCreation: true,
- bankName: "Taler DEVELOPMENT Bank",
- // Names and links for other demo sites to show in the navbar
- demoSites: [
- ["Exchange", "https://Exchnage.taler.test/"],
- ["Bank", "https://bank-ui.taler.test/"],
- ["Merchant", "https://merchant.taler.test/"],
- ],
-};
diff --git a/packages/demobank-ui/src/components/app.tsx b/packages/demobank-ui/src/components/app.tsx
index c787fa713..27898caeb 100644
--- a/packages/demobank-ui/src/components/app.tsx
+++ b/packages/demobank-ui/src/components/app.tsx
@@ -19,35 +19,45 @@ import {
getGlobalLogLevel,
setGlobalLogLevelFromString
} from "@gnu-taler/taler-util";
-import { TranslationProvider } from "@gnu-taler/web-util/browser";
+import { Loading, TranslationProvider } from "@gnu-taler/web-util/browser";
import { Fragment, FunctionalComponent, h } from "preact";
import { SWRConfig } from "swr";
import { BackendStateProvider } from "../context/backend.js";
import { BankCoreApiProvider } from "../context/config.js";
import { strings } from "../i18n/strings.js";
-import { bankUiSettings } from "../settings.js";
+import { BankUiSettings, fetchSettings } from "../settings.js";
import { Routing } from "../Routing.js";
import { BankFrame } from "../pages/BankFrame.js";
+import { useEffect, useState } from "preact/hooks";
+import { SettingsProvider } from "../context/settings.js";
const WITH_LOCAL_STORAGE_CACHE = false;
const App: FunctionalComponent = () => {
- const baseUrl = getInitialBackendBaseURL();
+ const [settings, setSettings] = useState<BankUiSettings>()
+ useEffect(() => {
+ fetchSettings(setSettings)
+ }, [])
+ if (!settings) return <Loading />;
+
+ const baseUrl = getInitialBackendBaseURL(settings.backendBaseURL);
return (
- <TranslationProvider source={strings}>
- <BackendStateProvider>
- <BankCoreApiProvider baseUrl={baseUrl} frameOnError={BankFrame}>
- <SWRConfig
- value={{
- provider: WITH_LOCAL_STORAGE_CACHE
- ? localStorageProvider
- : undefined,
- }}
- >
- <Routing />
- </SWRConfig>
- </BankCoreApiProvider>
- </BackendStateProvider>
- </TranslationProvider >
+ <SettingsProvider value={settings}>
+ <TranslationProvider source={strings}>
+ <BackendStateProvider>
+ <BankCoreApiProvider baseUrl={baseUrl} frameOnError={BankFrame}>
+ <SWRConfig
+ value={{
+ provider: WITH_LOCAL_STORAGE_CACHE
+ ? localStorageProvider
+ : undefined,
+ }}
+ >
+ <Routing />
+ </SWRConfig>
+ </BankCoreApiProvider>
+ </BackendStateProvider>
+ </TranslationProvider >
+ </SettingsProvider>
);
};
@@ -66,7 +76,7 @@ function localStorageProvider(): Map<unknown, unknown> {
export default App;
-function getInitialBackendBaseURL(): string {
+function getInitialBackendBaseURL(backendFromSettings: string | undefined): string {
const overrideUrl =
typeof localStorage !== "undefined"
? localStorage.getItem("bank-base-url")
@@ -75,13 +85,13 @@ function getInitialBackendBaseURL(): string {
if (!overrideUrl) {
//normal path
- if (!bankUiSettings.backendBaseURL) {
+ if (!backendFromSettings) {
console.error(
"ERROR: backendBaseURL was overridden by a setting file and missing. Setting value to 'window.origin'",
);
result = window.origin
} else {
- result = bankUiSettings.backendBaseURL;
+ result = backendFromSettings;
}
} else {
// testing/development path
diff --git a/packages/demobank-ui/src/context/settings.ts b/packages/demobank-ui/src/context/settings.ts
new file mode 100644
index 000000000..a14c14d15
--- /dev/null
+++ b/packages/demobank-ui/src/context/settings.ts
@@ -0,0 +1,44 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { ComponentChildren, createContext, h, VNode } from "preact";
+import { useContext } from "preact/hooks";
+import { BankUiSettings } from "../settings.js";
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+export type Type = BankUiSettings;
+
+const initial: BankUiSettings = {};
+const Context = createContext<Type>(initial);
+
+export const useSettingsContext = (): Type => useContext(Context);
+
+export const SettingsProvider = ({
+ children,
+ value,
+}: {
+ value: BankUiSettings,
+ children: ComponentChildren;
+}): VNode => {
+ return h(Context.Provider, {
+ value,
+ children,
+ });
+};
diff --git a/packages/demobank-ui/src/hooks/backend.ts b/packages/demobank-ui/src/hooks/backend.ts
index 93d647e73..863b47bf3 100644
--- a/packages/demobank-ui/src/hooks/backend.ts
+++ b/packages/demobank-ui/src/hooks/backend.ts
@@ -29,7 +29,6 @@ import {
useLocalStorage
} from "@gnu-taler/web-util/browser";
import { useSWRConfig } from "swr";
-import { bankUiSettings } from "../settings.js";
/**
* Has the information to reach and
diff --git a/packages/demobank-ui/src/hooks/circuit.ts b/packages/demobank-ui/src/hooks/circuit.ts
index d0d180a53..c0164d60a 100644
--- a/packages/demobank-ui/src/hooks/circuit.ts
+++ b/packages/demobank-ui/src/hooks/circuit.ts
@@ -34,9 +34,7 @@ export type TransferCalculation = {
};
type EstimatorFunction = (
amount: AmountJson,
- currency: string,
- sellFee: AmountJson,
- sellRate: number,
+ fee: AmountJson,
) => Promise<TransferCalculation>;
type CashoutEstimators = {
@@ -73,25 +71,19 @@ export function useEstimator(): CashoutEstimators {
const { state } = useBackendState();
const { api } = useBankCoreApiContext();
return {
- estimateByCredit: async (fiatAmount, regionalCurrency, fee, rate) => {
- // const resp = await api.getConversionInfoAPI().getCashoutRate({
- // credit: amount
- // });
- // if (resp.type === "fail") {
- // // can't happen
- // // not-supported: it should not be able to call this function
- // // wrong-calculation: we are using just one parameter
- // throw TalerError.fromDetail(resp.detail.code, {}, resp.detail.hint)
- // }
- const credit = fiatAmount;
- const beforeFee = Amounts.sub(credit, fee).amount;
-
- // const debit = Amounts.parseOrThrow(resp.body.amount_debit);
- //FIXME: remove this when endpoint works
- const debit = Amounts.add(
- Amounts.zeroOfCurrency(regionalCurrency),
- beforeFee
- ).amount;
+ estimateByCredit: async (fiatAmount, fee) => {
+ const resp = await api.getConversionInfoAPI().getCashoutRate({
+ credit: fiatAmount
+ });
+ if (resp.type === "fail") {
+ // can't happen
+ // not-supported: it should not be able to call this function
+ // wrong-calculation: we are using just one parameter
+ throw TalerError.fromDetail(resp.detail.code, {}, resp.detail.hint)
+ }
+ const credit = Amounts.parseOrThrow(resp.body.amount_credit);
+ const debit = Amounts.parseOrThrow(resp.body.amount_debit);
+ const beforeFee = Amounts.add(credit, fee).amount;
return {
debit,
@@ -99,19 +91,20 @@ export function useEstimator(): CashoutEstimators {
credit,
};
},
- estimateByDebit: async (regionalAmount, fiatCurrency, fee, rate) => {
- // const resp = await api.getConversionInfoAPI().getCashoutRate({ debit: amount });
- // if (resp.type === "fail") {
- // // can't happen
- // // not-supported: it should not be able to call this function
- // // wrong-calculation: we are using just one parameter
- // throw TalerError.fromDetail(resp.detail.code, {}, resp.detail.hint)
- // }
- // const credit = Amounts.parseOrThrow(resp.body.amount_credit);
- const debit = regionalAmount;
- const _credit = Amounts.parseOrThrow(regionalAmount);
- const beforeFee = { ..._credit, currency: fiatCurrency };
- const credit = Amounts.sub(beforeFee, fee).amount;
+ estimateByDebit: async (regionalAmount, fee) => {
+ const resp = await api.getConversionInfoAPI().getCashoutRate({
+ debit: regionalAmount
+ });
+ if (resp.type === "fail") {
+ // can't happen
+ // not-supported: it should not be able to call this function
+ // wrong-calculation: we are using just one parameter
+ throw TalerError.fromDetail(resp.detail.code, {}, resp.detail.hint)
+ }
+ const credit = Amounts.parseOrThrow(resp.body.amount_credit);
+ const debit = Amounts.parseOrThrow(resp.body.amount_debit);
+ const beforeFee = Amounts.add(credit, fee).amount;
+
return {
debit,
beforeFee,
diff --git a/packages/demobank-ui/src/hooks/settings.ts b/packages/demobank-ui/src/hooks/preferences.ts
index bd48ca680..a1525ac80 100644
--- a/packages/demobank-ui/src/hooks/settings.ts
+++ b/packages/demobank-ui/src/hooks/preferences.ts
@@ -25,7 +25,7 @@ import {
} from "@gnu-taler/taler-util";
import { buildStorageKey, useLocalStorage, useTranslationContext } from "@gnu-taler/web-util/browser";
-interface Settings {
+interface Preferences {
currentWithdrawalOperationId: string | undefined;
showWithdrawalSuccess: boolean;
showDemoDescription: boolean;
@@ -36,11 +36,11 @@ interface Settings {
}
-export function getAllBooleanSettings(): Array<keyof Settings> {
+export function getAllBooleanPreferences(): Array<keyof Preferences> {
return ["fastWithdrawal", "showDebugInfo", "showDemoDescription", "showInstallWallet", "showWithdrawalSuccess"]
}
-export function getLabelForSetting(k: keyof Settings, i18n: ReturnType<typeof useTranslationContext>["i18n"]): TranslatedString {
+export function getLabelForPreferences(k: keyof Preferences, i18n: ReturnType<typeof useTranslationContext>["i18n"]): TranslatedString {
switch (k) {
case "currentWithdrawalOperationId": return i18n.str`Current withdrawal operation`
case "maxWithdrawalAmount": return i18n.str`Max withdrawal amount`
@@ -52,8 +52,8 @@ export function getLabelForSetting(k: keyof Settings, i18n: ReturnType<typeof us
}
}
-export const codecForSettings = (): Codec<Settings> =>
- buildCodecForObject<Settings>()
+export const codecForPreferences = (): Codec<Preferences> =>
+ buildCodecForObject<Preferences>()
.property("currentWithdrawalOperationId", codecOptional(codecForString()))
.property("showWithdrawalSuccess", (codecForBoolean()))
.property("showDemoDescription", (codecForBoolean()))
@@ -63,7 +63,7 @@ export const codecForSettings = (): Codec<Settings> =>
.property("maxWithdrawalAmount", codecForNumber())
.build("Settings");
-const defaultSettings: Settings = {
+const defaultPreferences: Preferences = {
currentWithdrawalOperationId: undefined,
showWithdrawalSuccess: true,
showDemoDescription: true,
@@ -73,21 +73,21 @@ const defaultSettings: Settings = {
showDebugInfo: false,
};
-const BANK_SETTINGS_KEY = buildStorageKey(
- "bank-settings",
- codecForSettings(),
+const BANK_PREFERENCES_KEY = buildStorageKey(
+ "bank-preferences",
+ codecForPreferences(),
);
-export function useSettings(): [
- Readonly<Settings>,
- <T extends keyof Settings>(key: T, value: Settings[T]) => void,
+export function usePreferences(): [
+ Readonly<Preferences>,
+ <T extends keyof Preferences>(key: T, value: Preferences[T]) => void,
] {
const { value, update } = useLocalStorage(
- BANK_SETTINGS_KEY,
- defaultSettings,
+ BANK_PREFERENCES_KEY,
+ defaultPreferences,
);
- function updateField<T extends keyof Settings>(k: T, v: Settings[T]) {
+ function updateField<T extends keyof Preferences>(k: T, v: Preferences[T]) {
const newValue = { ...value, [k]: v };
update(newValue);
}
diff --git a/packages/demobank-ui/src/index.html b/packages/demobank-ui/src/index.html
index f702f30ea..3cc7f7fd2 100644
--- a/packages/demobank-ui/src/index.html
+++ b/packages/demobank-ui/src/index.html
@@ -29,8 +29,6 @@
href="data:;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////////////7//v38//78/P/+/fz//vz7///+/v/+/f3//vz7///+/v/+/fz//v38///////////////////////+/v3///7+/////////////////////////////////////////////////////////v3//v79///////+/v3///////r28v/ct5//06SG/9Gffv/Xqo7/7N/V/9e2nf/bsJb/6uDW/9Sskf/euKH/+/j2///////+/v3//////+3azv+/eE3/2rWd/9Kkhv/Vr5T/48i2/8J+VP/Qn3//3ryn/795Tf/WrpP/2LCW/8B6T//w4Nb///////Pn4P+/d0v/9u3n/+7d0v/EhV7//v///+HDr//fxLD/zph2/+TJt//8/Pv/woBX//Lm3f/y5dz/v3hN//bu6f/JjGn/4sW0///////Df1j/8OLZ//v6+P+/elH/+vj1//jy7f+/elL//////+zYzP/Eg13//////967p//MlHT/wn5X///////v4Nb/yY1s///////jw7H/06KG////////////z5t9/+fNvf//////x4pn//Pp4v/8+vn/w39X/8WEX///////5s/A/9CbfP//////27Oc/9y2n////////////9itlf/gu6f//////86Vdf/r2Mz//////8SCXP/Df1j//////+7d0v/KkG7//////+HBrf/VpYr////////////RnoH/5sq6///////Ii2n/8ubf//39/P/Cf1j/xohk/+bNvv//////wn5W//Tq4//58/D/wHxV//7+/f/59fH/v3xU//39/P/w4Nf/xIFb///////hw7H/yo9t/+/f1f/AeU3/+/n2/+nSxP/FhmD//////9qzm//Upon/4MSx/96+qf//////xINc/+3bz//48e3/v3hN//Pn3///////6M+//752S//gw6//06aK/8J+VP/kzLr/zZd1/8OCWv/q18r/17KZ/9Ooi//fv6r/v3dK/+vWyP///////v39///////27un/1aeK/9Opjv/m1cf/1KCC/9a0nP/n08T/0Jx8/82YdP/QnHz/16yR//jx7P///////v39///////+/f3///7+///////+//7//v7+///////+/v7//v/+/////////////////////////v7//v79///////////////////+/v/+/Pv//v39///+/v/+/Pv///7+//7+/f/+/Pv//v39//79/P/+/Pv///7+////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" />
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon" />
<title>Bank</title>
- <!-- Optional customization script. -->
- <script src="bank-ui-settings.js"></script>
<!-- Entry point for the bank SPA. -->
<script type="module" src="index.js"></script>
<link rel="stylesheet" href="index.css" />
diff --git a/packages/demobank-ui/src/pages/AccountPage/views.tsx b/packages/demobank-ui/src/pages/AccountPage/views.tsx
index 0f5236192..cfee684fa 100644
--- a/packages/demobank-ui/src/pages/AccountPage/views.tsx
+++ b/packages/demobank-ui/src/pages/AccountPage/views.tsx
@@ -18,7 +18,7 @@ import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { Attention } from "@gnu-taler/web-util/browser";
import { Transactions } from "../../components/Transactions/index.js";
-import { useSettings } from "../../hooks/settings.js";
+import { usePreferences } from "../../hooks/preferences.js";
import { PaymentOptions } from "../PaymentOptions.js";
import { State } from "./index.js";
@@ -32,7 +32,7 @@ const IS_PUBLIC_ACCOUNT_ENABLED = false
function ShowDemoInfo(): VNode {
const { i18n } = useTranslationContext();
- const [settings, updateSettings] = useSettings();
+ const [settings, updateSettings] = usePreferences();
if (!settings.showDemoDescription) return <Fragment />
return <Attention title={i18n.str`This is a demo bank`} onClose={() => {
updateSettings("showDemoDescription", false);
diff --git a/packages/demobank-ui/src/pages/BankFrame.tsx b/packages/demobank-ui/src/pages/BankFrame.tsx
index f0baae3a3..5fef04b66 100644
--- a/packages/demobank-ui/src/pages/BankFrame.tsx
+++ b/packages/demobank-ui/src/pages/BankFrame.tsx
@@ -20,9 +20,9 @@ import { ComponentChildren, Fragment, VNode, h } from "preact";
import { useEffect, useErrorBoundary } from "preact/hooks";
import { useAccountDetails } from "../hooks/access.js";
import { useBackendState } from "../hooks/backend.js";
-import { getAllBooleanSettings, getLabelForSetting, useSettings } from "../hooks/settings.js";
-import { bankUiSettings } from "../settings.js";
+import { getAllBooleanPreferences, getLabelForPreferences, usePreferences } from "../hooks/preferences.js";
import { RenderAmount } from "./PaytoWireTransferForm.js";
+import { useSettingsContext } from "../context/settings.js";
const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined;
const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : undefined;
@@ -37,7 +37,8 @@ export function BankFrame({
}): VNode {
const { i18n } = useTranslationContext();
const backend = useBackendState();
- const [settings, updateSettings] = useSettings();
+ const settings = useSettingsContext();
+ const [preferences, updatePreferences] = usePreferences();
const [error, resetError] = useErrorBoundary();
@@ -59,12 +60,12 @@ export function BankFrame({
<div class="bg-indigo-600 pb-32">
<Header
title="Bank"
- iconLinkURL={bankUiSettings.iconLinkURL ?? "#"}
+ iconLinkURL={settings.iconLinkURL ?? "#"}
onLogout={backend.state.status !== "loggedIn" ? undefined : () => {
backend.logOut()
- updateSettings("currentWithdrawalOperationId", undefined);
+ updatePreferences("currentWithdrawalOperationId", undefined);
}}
- sites={bankUiSettings.demoSites ?? []}
+ sites={settings.demoSites ?? new Array<Array<string>>(new Array<string>())}
supportedLangs={["en", "es", "de"]}
>
<li>
@@ -72,18 +73,18 @@ export function BankFrame({
<i18n.Translate>Preferences</i18n.Translate>
</div>
<ul role="list" class="space-y-1">
- {getAllBooleanSettings().map(set => {
- const isOn: boolean = !!settings[set]
+ {getAllBooleanPreferences().map(set => {
+ const isOn: boolean = !!preferences[set]
return <li class="mt-2 pl-2">
<div class="flex items-center justify-between">
<span class="flex flex-grow flex-col">
<span class="text-sm text-black font-medium leading-6 " id="availability-label">
- {getLabelForSetting(set, i18n)}
+ {getLabelForPreferences(set, i18n)}
</span>
</span>
<button type="button" data-enabled={isOn} class="bg-indigo-600 data-[enabled=false]:bg-gray-200 relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2" role="switch" aria-checked="false" aria-labelledby="availability-label" aria-describedby="availability-description"
- onClick={() => { updateSettings(set, !isOn); }}>
+ onClick={() => { updatePreferences(set, !isOn); }}>
<span aria-hidden="true" data-enabled={isOn} class="translate-x-5 data-[enabled=false]:translate-x-0 pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out"></span>
</button>
</div>
@@ -130,7 +131,7 @@ export function BankFrame({
}
function MaybeShowDebugInfo({ info }: { info: any }): VNode {
- const [settings] = useSettings()
+ const [settings] = usePreferences()
if (settings.showDebugInfo) {
return <pre class="whitespace-break-spaces ">
{info}
diff --git a/packages/demobank-ui/src/pages/LoginForm.tsx b/packages/demobank-ui/src/pages/LoginForm.tsx
index 018416390..02ec75dbf 100644
--- a/packages/demobank-ui/src/pages/LoginForm.tsx
+++ b/packages/demobank-ui/src/pages/LoginForm.tsx
@@ -15,18 +15,14 @@
*/
import { TranslatedString } from "@gnu-taler/taler-util";
-import { Notification, useLocalNotification, useTranslationContext } from "@gnu-taler/web-util/browser";
+import { LocalNotificationBanner, ShowInputErrorLabel, useLocalNotification, useTranslationContext } from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useEffect, useRef, useState } from "preact/hooks";
-import { ShowInputErrorLabel } from "@gnu-taler/web-util/browser";
import { useBankCoreApiContext } from "../context/config.js";
import { useBackendState } from "../hooks/backend.js";
-import { bankUiSettings } from "../settings.js";
-import { undefinedIfEmpty, withRuntimeErrorHandling } from "../utils.js";
-import { assertUnreachable } from "./WithdrawalOperationPage.js";
+import { undefinedIfEmpty } from "../utils.js";
import { doAutoFocus } from "./PaytoWireTransferForm.js";
-import { Attention } from "@gnu-taler/web-util/browser";
-import { LocalNotificationBanner } from "@gnu-taler/web-util/browser";
+import { assertUnreachable } from "./WithdrawalOperationPage.js";
/**
@@ -40,6 +36,7 @@ export function LoginForm({ reason, onRegister }: { reason?: "not-found" | "forb
const { i18n } = useTranslationContext();
const { api } = useBankCoreApiContext();
const [notification, notify, handleError] = useLocalNotification()
+ const {config} = useBankCoreApiContext();
/**
* Register form may be shown in the initialization step.
@@ -208,7 +205,7 @@ export function LoginForm({ reason, onRegister }: { reason?: "not-found" | "forb
</div>}
</form>
- {bankUiSettings.allowRegistrations && onRegister &&
+ {config.allow_registrations && onRegister &&
<p class="mt-10 text-center text-sm text-gray-500 border-t">
<button type="submit"
class="flex mt-4 rounded-md bg-blue-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
diff --git a/packages/demobank-ui/src/pages/OperationState/state.ts b/packages/demobank-ui/src/pages/OperationState/state.ts
index 2d33ff78b..30f7419f0 100644
--- a/packages/demobank-ui/src/pages/OperationState/state.ts
+++ b/packages/demobank-ui/src/pages/OperationState/state.ts
@@ -21,12 +21,12 @@ import { mutate } from "swr";
import { useBankCoreApiContext } from "../../context/config.js";
import { useWithdrawalDetails } from "../../hooks/access.js";
import { useBackendState } from "../../hooks/backend.js";
-import { useSettings } from "../../hooks/settings.js";
+import { usePreferences } from "../../hooks/preferences.js";
import { assertUnreachable } from "../WithdrawalOperationPage.js";
import { Props, State } from "./index.js";
export function useComponentState({ currency, onClose }: Props): utils.RecursiveState<State> {
- const [settings, updateSettings] = useSettings()
+ const [settings, updateSettings] = usePreferences()
const { state: credentials } = useBackendState()
const creds = credentials.status !== "loggedIn" ? undefined : credentials
const { api } = useBankCoreApiContext()
diff --git a/packages/demobank-ui/src/pages/OperationState/views.tsx b/packages/demobank-ui/src/pages/OperationState/views.tsx
index e7db566ea..a06147039 100644
--- a/packages/demobank-ui/src/pages/OperationState/views.tsx
+++ b/packages/demobank-ui/src/pages/OperationState/views.tsx
@@ -20,7 +20,7 @@ import { Fragment, VNode, h } from "preact";
import { useEffect, useMemo, useState } from "preact/hooks";
import { QR } from "../../components/QR.js";
import { ShowInputErrorLabel } from "@gnu-taler/web-util/browser";
-import { useSettings } from "../../hooks/settings.js";
+import { usePreferences } from "../../hooks/preferences.js";
import { undefinedIfEmpty } from "../../utils.js";
import { State } from "./index.js";
import { LocalNotificationBanner } from "@gnu-taler/web-util/browser";
@@ -46,7 +46,7 @@ export function InvalidReserveView({ reserve, onClose }: State.InvalidReserve) {
export function NeedConfirmationView({ error, onAbort: doAbort, onConfirm: doConfirm, busy }: State.NeedConfirmation) {
const { i18n } = useTranslationContext()
- const [settings] = useSettings()
+ const [settings] = usePreferences()
const [notification, notify, errorHandler] = useLocalNotification()
const captchaNumbers = useMemo(() => {
@@ -309,7 +309,7 @@ export function AbortedView({ error, onClose }: State.Aborted) {
export function ConfirmedView({ error, onClose }: State.Confirmed) {
const { i18n } = useTranslationContext();
- const [settings, updateSettings] = useSettings()
+ const [settings, updateSettings] = usePreferences()
return (
<Fragment>
diff --git a/packages/demobank-ui/src/pages/PaymentOptions.tsx b/packages/demobank-ui/src/pages/PaymentOptions.tsx
index 2e756b86d..76d20867e 100644
--- a/packages/demobank-ui/src/pages/PaymentOptions.tsx
+++ b/packages/demobank-ui/src/pages/PaymentOptions.tsx
@@ -20,7 +20,7 @@ import { h, VNode } from "preact";
import { useState } from "preact/hooks";
import { PaytoWireTransferForm, doAutoFocus } from "./PaytoWireTransferForm.js";
import { WalletWithdrawForm } from "./WalletWithdrawForm.js";
-import { useSettings } from "../hooks/settings.js";
+import { usePreferences } from "../hooks/preferences.js";
/**
* Let the user choose a payment option,
@@ -28,7 +28,7 @@ import { useSettings } from "../hooks/settings.js";
*/
export function PaymentOptions({ limit, goToConfirmOperation }: { limit: AmountJson, goToConfirmOperation: (id: string) => void }): VNode {
const { i18n } = useTranslationContext();
- const [settings] = useSettings();
+ const [settings] = usePreferences();
const [tab, setTab] = useState<"charge-wallet" | "wire-transfer" | undefined>();
diff --git a/packages/demobank-ui/src/pages/RegistrationPage.tsx b/packages/demobank-ui/src/pages/RegistrationPage.tsx
index fdaa28bbb..9c3b21097 100644
--- a/packages/demobank-ui/src/pages/RegistrationPage.tsx
+++ b/packages/demobank-ui/src/pages/RegistrationPage.tsx
@@ -15,18 +15,18 @@
*/
import { AccessToken, Logger, TranslatedString } from "@gnu-taler/taler-util";
import {
+ LocalNotificationBanner,
+ ShowInputErrorLabel,
useLocalNotification,
useTranslationContext
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
-import { ShowInputErrorLabel } from "@gnu-taler/web-util/browser";
import { useBankCoreApiContext } from "../context/config.js";
import { useBackendState } from "../hooks/backend.js";
-import { bankUiSettings } from "../settings.js";
-import { undefinedIfEmpty, withRuntimeErrorHandling } from "../utils.js";
+import { undefinedIfEmpty } from "../utils.js";
import { getRandomPassword, getRandomUsername } from "./rnd.js";
-import { LocalNotificationBanner } from "@gnu-taler/web-util/browser";
+import { useSettingsContext } from "../context/settings.js";
const logger = new Logger("RegistrationPage");
@@ -38,7 +38,8 @@ export function RegistrationPage({
onCancel: () => void;
}): VNode {
const { i18n } = useTranslationContext();
- if (!bankUiSettings.allowRegistrations) {
+ const {config} = useBankCoreApiContext();
+ if (!config.allow_registrations) {
return (
<p>{i18n.str`Currently, the bank is not accepting new registrations!`}</p>
);
@@ -62,6 +63,7 @@ function RegistrationForm({ onComplete, onCancel }: { onComplete: () => void, on
const [email, setEmail] = useState<string | undefined>();
const [repeatPassword, setRepeatPassword] = useState<string | undefined>();
const [notification, notify, handleError] = useLocalNotification()
+ const settings = useSettingsContext();
const { api } = useBankCoreApiContext()
// const { register } = useTestingAPI();
@@ -177,7 +179,8 @@ function RegistrationForm({ onComplete, onCancel }: { onComplete: () => void, on
async function doRandomRegistration(tries: number = 3) {
const user = getRandomUsername();
- const pass = getRandomPassword();
+
+ const pass = settings.simplePasswordForRandomAccounts ? "123" : getRandomPassword();
const username = `_${user.first}-${user.second}_`
await doRegistrationAndLogin(name, username, pass)
onComplete();
@@ -389,7 +392,7 @@ function RegistrationForm({ onComplete, onCancel }: { onComplete: () => void, on
</form>
- {bankUiSettings.allowRandomAccountCreation &&
+ {settings.allowRandomAccountCreation &&
<p class="mt-10 text-center text-sm text-gray-500 border-t">
<button type="submit"
class="flex mt-4 w-full justify-center rounded-md bg-green-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600"
diff --git a/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx b/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx
index a9a661c25..5eef95f1e 100644
--- a/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx
+++ b/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx
@@ -32,7 +32,7 @@ import { useState } from "preact/hooks";
import { Attention } from "@gnu-taler/web-util/browser";
import { useBankCoreApiContext } from "../context/config.js";
import { useBackendState } from "../hooks/backend.js";
-import { useSettings } from "../hooks/settings.js";
+import { usePreferences } from "../hooks/preferences.js";
import { undefinedIfEmpty, withRuntimeErrorHandling } from "../utils.js";
import { OperationState } from "./OperationState/index.js";
import { InputAmount, doAutoFocus } from "./PaytoWireTransferForm.js";
@@ -50,7 +50,7 @@ function OldWithdrawalForm({ goToConfirmOperation, limit, onCancel, focus }: {
onCancel: () => void;
}): VNode {
const { i18n } = useTranslationContext();
- const [settings, updateSettings] = useSettings()
+ const [settings, updateSettings] = usePreferences()
const { state: credentials } = useBackendState();
const creds = credentials.status !== "loggedIn" ? undefined : credentials
@@ -240,7 +240,7 @@ export function WalletWithdrawForm({
onCancel: () => void;
}): VNode {
const { i18n } = useTranslationContext();
- const [settings, updateSettings] = useSettings()
+ const [settings, updateSettings] = usePreferences()
return (<div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-10 md:grid-cols-3 bg-gray-100 my-4 px-4 pb-4 rounded-lg">
<div class="px-4 sm:px-0">
diff --git a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
index 7fec76d2f..be8ff8b58 100644
--- a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
+++ b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
@@ -33,7 +33,7 @@ import { useMemo, useState } from "preact/hooks";
import { mutate } from "swr";
import { ShowInputErrorLabel } from "@gnu-taler/web-util/browser";
import { useBankCoreApiContext } from "../context/config.js";
-import { useSettings } from "../hooks/settings.js";
+import { usePreferences } from "../hooks/preferences.js";
import { undefinedIfEmpty, withRuntimeErrorHandling } from "../utils.js";
import { RenderAmount } from "./PaytoWireTransferForm.js";
import { assertUnreachable } from "./WithdrawalOperationPage.js";
@@ -60,7 +60,7 @@ export function WithdrawalConfirmationQuestion({
withdrawUri,
}: Props): VNode {
const { i18n } = useTranslationContext();
- const [settings, updateSettings] = useSettings()
+ const [settings, updateSettings] = usePreferences()
const captchaNumbers = useMemo(() => {
return {
diff --git a/packages/demobank-ui/src/pages/WithdrawalOperationPage.tsx b/packages/demobank-ui/src/pages/WithdrawalOperationPage.tsx
index 5ed57a0f7..7060b7a98 100644
--- a/packages/demobank-ui/src/pages/WithdrawalOperationPage.tsx
+++ b/packages/demobank-ui/src/pages/WithdrawalOperationPage.tsx
@@ -25,7 +25,7 @@ import {
import { Fragment, VNode, h } from "preact";
import { Attention } from "@gnu-taler/web-util/browser";
import { useBankCoreApiContext } from "../context/config.js";
-import { useSettings } from "../hooks/settings.js";
+import { usePreferences } from "../hooks/preferences.js";
import { WithdrawalQRCode } from "./WithdrawalQRCode.js";
const logger = new Logger("AccountPage");
@@ -44,7 +44,7 @@ export function WithdrawalOperationPage({
});
const parsedUri = parseWithdrawUri(uri);
const { i18n } = useTranslationContext();
- const [settings, updateSettings] = useSettings();
+ const [settings, updateSettings] = usePreferences();
if (!parsedUri) {
return <Attention type="danger" title={i18n.str`The Withdrawal URI is not valid`}>
diff --git a/packages/demobank-ui/src/pages/business/CreateCashout.tsx b/packages/demobank-ui/src/pages/business/CreateCashout.tsx
index 1838dbda3..c5f4ebc4e 100644
--- a/packages/demobank-ui/src/pages/business/CreateCashout.tsx
+++ b/packages/demobank-ui/src/pages/business/CreateCashout.tsx
@@ -77,7 +77,7 @@ export function CreateCashout({
estimateByCredit: calculateFromCredit,
estimateByDebit: calculateFromDebit,
} = useEstimator();
- const { api, config } = useBankCoreApiContext()
+ const { config } = useBankCoreApiContext()
const [form, setForm] = useState<Partial<FormType>>({ isDebit: true, amount: "2" });
const [notification, notify, handleError] = useLocalNotification()
const info = useConversionInfo();
@@ -108,35 +108,29 @@ export function CreateCashout({
return <ErrorLoading error={info} />
}
+ const conversionInfo = info.body.conversion_info
+ if (!conversionInfo) {
+ return <div>conversion enabled but server replied without conversion_info</div>
+ }
+
const account = {
balance: Amounts.parseOrThrow(resultAccount.body.balance.amount),
balanceIsDebit: resultAccount.body.balance.credit_debit_indicator == "debit",
debitThreshold: Amounts.parseOrThrow(resultAccount.body.debit_threshold)
}
- const { fiat_currency, regional_currency, cashout_ratio, cashout_fee } = info.body
+ const {fiat_currency, regional_currency} = info.body
const regionalZero = Amounts.zeroOfCurrency(regional_currency);
const fiatZero = Amounts.zeroOfCurrency(fiat_currency);
const limit = account.balanceIsDebit
? Amounts.sub(account.debitThreshold, account.balance).amount
: Amounts.add(account.balance, account.debitThreshold).amount;
- const zeroCalc = { debit: regionalZero, credit: fiatZero, beforeFee: regionalZero };
+ const zeroCalc = { debit: regionalZero, credit: fiatZero, beforeFee: fiatZero };
const [calc, setCalc] = useState(zeroCalc);
-
- const sellRate = Number.parseFloat(cashout_ratio);
- const sellFee = !cashout_fee
- ? fiatZero
- : Amounts.parseOrThrow(cashout_fee);
-
- if (sellRate === undefined || sellRate < 0) return <div>error rate d
- <pre>
- {JSON.stringify(info.body, undefined, 2)}
- </pre>
- </div>;
-
- const safeSellRate = sellRate
-
+ console.log(calc)
+ const sellFee = Amounts.parseOrThrow(conversionInfo.cashout_fee);
+ const sellRate = conversionInfo.cashout_ratio
/**
* can be in regional currency or fiat currency
* depending on the isDebit flag
@@ -150,8 +144,8 @@ export function CreateCashout({
await handleError(async () => {
if (Amounts.isNonZero(inputAmount)) {
const resp = await (form.isDebit ?
- calculateFromDebit(inputAmount, fiat_currency, sellFee, safeSellRate) :
- calculateFromCredit(inputAmount, regional_currency, sellFee, safeSellRate));
+ calculateFromDebit(inputAmount, sellFee) :
+ calculateFromCredit(inputAmount, sellFee));
setCalc(resp)
}
})
diff --git a/packages/demobank-ui/src/pages/rnd.ts b/packages/demobank-ui/src/pages/rnd.ts
index 32c3a934f..46111425e 100644
--- a/packages/demobank-ui/src/pages/rnd.ts
+++ b/packages/demobank-ui/src/pages/rnd.ts
@@ -1,5 +1,4 @@
import { createEddsaKeyPair, encodeCrock, getRandomBytes } from "@gnu-taler/taler-util"
-import { bankUiSettings } from "../settings.js"
const noun = [
@@ -2890,6 +2889,5 @@ export function getRandomUsername(): { first: string, second: string } {
}
export function getRandomPassword(): string {
- if (bankUiSettings.simplePasswordForRandomAccounts) return "123"
return encodeCrock(getRandomBytes(16))
} \ No newline at end of file
diff --git a/packages/demobank-ui/src/settings.json b/packages/demobank-ui/src/settings.json
new file mode 100644
index 000000000..8d5b149b5
--- /dev/null
+++ b/packages/demobank-ui/src/settings.json
@@ -0,0 +1,12 @@
+{
+ "backendBaseURL": "http://bank.taler.test:1180/",
+ "showDemoNav": true,
+ "simplePasswordForRandomAccounts": true,
+ "allowRandomAccountCreation": true,
+ "bankName": "Taler DEVELOPMENT Bank",
+ "demoSites": [
+ ["Exchange", "https://Exchnage.taler.test/"],
+ ["Bank", "https://bank-ui.taler.test/"],
+ ["Merchant", "https://merchant.taler.test/"]
+ ]
+}
diff --git a/packages/demobank-ui/src/settings.ts b/packages/demobank-ui/src/settings.ts
index f17d1d511..a9c63857b 100644
--- a/packages/demobank-ui/src/settings.ts
+++ b/packages/demobank-ui/src/settings.ts
@@ -14,15 +14,16 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
+import { Codec, buildCodecForObject, codecForBoolean, codecForList, codecForString, codecOptional } from "@gnu-taler/taler-util";
+
export interface BankUiSettings {
backendBaseURL?: string;
- allowRegistrations?: boolean;
iconLinkURL?: string;
showDemoNav?: boolean;
simplePasswordForRandomAccounts?: boolean;
allowRandomAccountCreation?: boolean;
bankName?: string;
- demoSites?: [string, string][];
+ demoSites?: Array<Array<string>>;
}
/**
@@ -31,7 +32,6 @@ export interface BankUiSettings {
const defaultSettings: BankUiSettings = {
backendBaseURL: "https://bank.demo.taler.net/demobanks/default/",
iconLinkURL: "https://demo.taler.net/",
- allowRegistrations: true,
bankName: "Taler Bank",
showDemoNav: true,
simplePasswordForRandomAccounts: true,
@@ -45,7 +45,26 @@ const defaultSettings: BankUiSettings = {
],
};
-export const bankUiSettings: BankUiSettings =
- "talerBankSettings" in globalThis
- ? (globalThis as any).talerBankSettings
- : defaultSettings;
+const codecForBankUISettings = (): Codec<BankUiSettings> =>
+ buildCodecForObject<BankUiSettings>()
+ .property("allowRandomAccountCreation", codecOptional(codecForBoolean()))
+ .property("backendBaseURL", codecOptional(codecForString()))
+ .property("bankName", codecOptional(codecForString()))
+ .property("demoSites", codecOptional(codecForList(codecForList(codecForString()))))
+ .property("iconLinkURL", codecOptional(codecForString()))
+ .property("showDemoNav", codecOptional(codecForBoolean()))
+ .property("simplePasswordForRandomAccounts", codecOptional(codecForBoolean()))
+ .build("BankUiSettings");
+
+export function fetchSettings(listener: (s: BankUiSettings) => void): void {
+ fetch("./settings.json")
+ .then(resp => resp.json())
+ .then(json => codecForBankUISettings().decode(json))
+ .then(listener)
+ .catch(e => {
+ console.log("failed to fetch settings", e)
+ listener(defaultSettings)
+ })
+}
+
+
diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts
index 3ef0ff76c..0ecc08b33 100644
--- a/packages/taler-util/src/http-client/types.ts
+++ b/packages/taler-util/src/http-client/types.ts
@@ -754,29 +754,21 @@ export const codecForConversionInfo =
buildCodecForObject<TalerBankConversionApi.ConversionInfo>()
.property("cashin_fee", codecForAmountString())
.property("cashin_min_amount", codecForAmountString())
- .property("cashin_ratio", codecForString())
- // .property("cashin_ratio", codecForDecimalNumber())
- .property(
- "cashin_rounding_mode",
- codecForEither(
- codecForConstString("zero"),
- codecForConstString("up"),
- codecForConstString("nearest"),
- ),
- )
+ .property("cashin_ratio", codecForDecimalNumber())
+ .property("cashin_rounding_mode", codecForEither(
+ codecForConstString("zero"),
+ codecForConstString("up"),
+ codecForConstString("nearest")
+ ))
.property("cashin_tiny_amount", codecForAmountString())
.property("cashout_fee", codecForAmountString())
.property("cashout_min_amount", codecForAmountString())
- .property("cashout_ratio", codecForString())
- // .property("cashout_ratio", codecForDecimalNumber())
- .property(
- "cashout_rounding_mode",
- codecForEither(
- codecForConstString("zero"),
- codecForConstString("up"),
- codecForConstString("nearest"),
- ),
- )
+ .property("cashout_ratio", codecForDecimalNumber())
+ .property("cashout_rounding_mode", codecForEither(
+ codecForConstString("zero"),
+ codecForConstString("up"),
+ codecForConstString("nearest")
+ ))
.property("cashout_tiny_amount", codecForAmountString())
.build("ConversionBankConfig.ConversionInfo");
@@ -792,34 +784,10 @@ export const codecForConversionBankConfig =
)
.property("fiat_currency", codecForString())
.property("fiat_currency_specification", codecForCurrencySpecificiation())
- // .property("conversion_info", codecOptional(codecForConversionInfo()))
- ////////////////////////// remove this
- .property("cashin_fee", codecForAmountString())
- .property("cashin_min_amount", codecForAmountString())
- .property("cashin_ratio", codecForString())
- .property(
- "cashin_rounding_mode",
- codecForEither(
- codecForConstString("zero"),
- codecForConstString("up"),
- codecForConstString("nearest"),
- ),
- )
- .property("cashin_tiny_amount", codecForAmountString())
- .property("cashout_fee", codecForAmountString())
- .property("cashout_min_amount", codecForAmountString())
- .property("cashout_ratio", codecForString())
- .property(
- "cashout_rounding_mode",
- codecForEither(
- codecForConstString("zero"),
- codecForConstString("up"),
- codecForConstString("nearest"),
- ),
- )
- .property("cashout_tiny_amount", codecForAmountString())
- //////////////////////////
- .build("ConversionBankConfig.IntegrationConfig");
+
+ .property("conversion_info", codecOptional(codecForConversionInfo()))
+ .build("ConversionBankConfig.IntegrationConfig")
+
// export const codecFor =
// (): Codec<TalerWireGatewayApi.PublicAccountsResponse> =>
// buildCodecForObject<TalerWireGatewayApi.PublicAccountsResponse>()
@@ -833,7 +801,7 @@ type EddsaSignature = string;
type BlindedRsaSignature = string;
type Base32 = string;
-type DecimalNumber = number;
+type DecimalNumber = string;
type RsaSignature = string;
// The type of a coin's blinded envelope depends on the cipher that is used
// for signing with a denomination key.
@@ -859,11 +827,10 @@ interface CSCoinEnvelope {
// a 256-bit nonce, converted to Crockford Base32.
type DenominationBlindingKeyP = string;
-const codecForURL = codecForString;
-const codecForLibtoolVersion = codecForString;
-const codecForCurrencyName = codecForString;
-const codecForEddsaSignature = codecForString;
-const codecForDecimalNumber = codecForNumber;
+const codecForURL = codecForString
+const codecForLibtoolVersion = codecForString
+const codecForCurrencyName = codecForString
+const codecForDecimalNumber = codecForString
enum TanChannel {
SMS = "sms",
@@ -1065,12 +1032,10 @@ export namespace TalerRevenueApi {
export namespace TalerBankConversionApi {
export interface ConversionInfo {
// Exchange rate to buy regional currency from fiat
- // cashin_ratio: DecimalNumber;
- cashin_ratio: string;
+ cashin_ratio: DecimalNumber;
// Exchange rate to sell regional currency for fiat
- // cashout_ratio: DecimalNumber;
- cashout_ratio: string;
+ cashout_ratio: DecimalNumber;
// Fee to subtract after applying the cashin ratio.
cashin_fee: AmountString;
@@ -1097,7 +1062,7 @@ export namespace TalerBankConversionApi {
cashout_rounding_mode: "zero" | "up" | "nearest";
}
- export interface IntegrationConfig extends ConversionInfo {
+ export interface IntegrationConfig {
// libtool-style representation of the Bank protocol version, see
// https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
// The format is "current:revision:age".
@@ -1120,7 +1085,7 @@ export namespace TalerBankConversionApi {
// Extra conversion rate information.
// Only present if server opts in to report the static conversion rate.
- // conversion_info?: ConversionInfo
+ conversion_info?: ConversionInfo
}
export interface CashinConversionResponse {
diff --git a/packages/web-util/src/components/Header.tsx b/packages/web-util/src/components/Header.tsx
index bde0688dc..0ffc57417 100644
--- a/packages/web-util/src/components/Header.tsx
+++ b/packages/web-util/src/components/Header.tsx
@@ -3,7 +3,8 @@ import { LangSelector, useTranslationContext } from "../index.browser.js";
import { ComponentChildren, Fragment, VNode, h } from "preact";
import logo from "../assets/logo-2021.svg";
-export function Header({ title, iconLinkURL, sites, supportedLangs, onLogout, children }: { title: string, iconLinkURL: string, children?: ComponentChildren, onLogout: (() => void) | undefined, sites: [string, string][], supportedLangs: string[] }): VNode {
+export function Header({ title, iconLinkURL, sites, supportedLangs, onLogout, children }:
+ { title: string, iconLinkURL: string, children?: ComponentChildren, onLogout: (() => void) | undefined, sites: Array<Array<string>>, supportedLangs: string[] }): VNode {
const { i18n } = useTranslationContext();
const [open, setOpen] = useState(false)
return <Fragment>
@@ -28,7 +29,9 @@ export function Header({ title, iconLinkURL, sites, supportedLangs, onLogout, ch
{sites.length !== 0 &&
<div class="flex flex-1 space-x-4">
{/* <!-- Current: "bg-indigo-700 text-white", Default: "text-white hover:bg-indigo-500 hover:bg-opacity-75" --> */}
- {sites.map(([name, url]) => {
+ {sites.map((site) => {
+ if (site.length !== 2) return;
+ const [name, url] = site
return <a href={url} class="text-white hover:bg-indigo-500 hover:bg-opacity-75 rounded-md py-2 px-3 text-sm font-medium">{name}</a>
})}
</div>