[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-wallet-core] 01/02: settings and preferences, getting conversion
From: |
gnunet |
Subject: |
[taler-wallet-core] 01/02: settings and preferences, getting conversion info |
Date: |
Wed, 22 Nov 2023 19:20:43 +0100 |
This is an automated email from the git hooks/post-receive script.
sebasjm pushed a commit to branch master
in repository wallet-core.
commit 33c0267b37eecf44dc9f04e124eb44d27cba700c
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Wed Nov 22 13:33:44 2023 -0300
settings and preferences, getting conversion info
---
packages/demobank-ui/dev.mjs | 4 +-
packages/demobank-ui/src/Routing.tsx | 10 ++-
packages/demobank-ui/src/bank-ui-settings.js | 19 -----
packages/demobank-ui/src/components/app.tsx | 52 +++++++------
.../{dev.mjs => src/context/settings.ts} | 53 +++++++-------
packages/demobank-ui/src/hooks/backend.ts | 1 -
packages/demobank-ui/src/hooks/circuit.ts | 63 +++++++---------
.../src/hooks/{settings.ts => preferences.ts} | 30 ++++----
packages/demobank-ui/src/index.html | 2 -
.../demobank-ui/src/pages/AccountPage/views.tsx | 4 +-
packages/demobank-ui/src/pages/BankFrame.tsx | 23 +++---
packages/demobank-ui/src/pages/LoginForm.tsx | 13 ++--
.../demobank-ui/src/pages/OperationState/state.ts | 4 +-
.../demobank-ui/src/pages/OperationState/views.tsx | 6 +-
packages/demobank-ui/src/pages/PaymentOptions.tsx | 4 +-
.../demobank-ui/src/pages/RegistrationPage.tsx | 17 +++--
.../demobank-ui/src/pages/WalletWithdrawForm.tsx | 6 +-
.../src/pages/WithdrawalConfirmationQuestion.tsx | 4 +-
.../src/pages/WithdrawalOperationPage.tsx | 4 +-
.../src/pages/business/CreateCashout.tsx | 32 ++++----
packages/demobank-ui/src/pages/rnd.ts | 2 -
packages/demobank-ui/src/settings.json | 12 +++
packages/demobank-ui/src/settings.ts | 33 +++++++--
packages/taler-util/src/http-client/types.ts | 85 +++++++---------------
packages/web-util/src/components/Header.tsx | 7 +-
25 files changed, 235 insertions(+), 255 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/dev.mjs
b/packages/demobank-ui/src/context/settings.ts
old mode 100755
new mode 100644
similarity index 53%
copy from packages/demobank-ui/dev.mjs
copy to packages/demobank-ui/src/context/settings.ts
index 8b04155f4..a14c14d15
--- a/packages/demobank-ui/dev.mjs
+++ b/packages/demobank-ui/src/context/settings.ts
@@ -1,4 +1,3 @@
-#!/usr/bin/env node
/*
This file is part of GNU Taler
(C) 2022 Taler Systems S.A.
@@ -15,27 +14,31 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-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 build = initializeDev({
- type: "development",
- source: {
- js: devEntryPoints,
- assets: [{ base: "src", files: ["src/index.html"] }],
- },
- destination: "./dist/dev",
- public: "/app",
- css: "postcss",
-});
-
-await build();
-
-serve({
- folder: "./dist/dev",
- port: 8080,
- source: "./src",
- onSourceUpdate: build,
-});
+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
similarity index 78%
rename from packages/demobank-ui/src/hooks/settings.ts
rename to 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/Qn
[...]
<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>
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.