taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit f69521e9ef7422acbc8f8e175cc64c28a32f9f0b
parent 8cc7e0a1a01f6d5515ade6fc5748ab3b42320244
Author: Florian Dold <dold@taler.net>
Date:   Mon, 31 Aug 2026 19:57:45 +0200

remove unused exports and dead modules

Diffstat:
Mpackages/anastasis-core/src/provider-types.ts | 11-----------
Mpackages/anastasis-core/src/reducer-types.ts | 8--------
Dpackages/anastasis-webui/src/components/fields/ImageInput.tsx | 93-------------------------------------------------------------------------------
Dpackages/anastasis-webui/src/components/menu/LangSelector.tsx | 92-------------------------------------------------------------------------------
Mpackages/anastasis-webui/src/components/menu/index.tsx | 62--------------------------------------------------------------
Dpackages/anastasis-webui/src/hooks/index.ts | 74--------------------------------------------------------------------------
Mpackages/anastasis-webui/src/hooks/useLocalStorage.ts | 31-------------------------------
Dpackages/challenger-webui/src/context/preferences.ts | 82-------------------------------------------------------------------------------
Mpackages/challenger-webui/src/context/settings.ts | 3---
Mpackages/challenger-webui/src/hooks/session.ts | 8--------
Mpackages/challenger-webui/src/pages/AskChallenge.tsx | 13-------------
Mpackages/challenger-webui/src/pages/CallengeCompleted.tsx | 3---
Dpackages/challenger-webui/src/pages/MissingParams.tsx | 20--------------------
Dpackages/challenger-webui/src/pages/NonceNotFound.tsx | 42------------------------------------------
Mpackages/idb-bridge/src/MemoryBackend.ts | 44--------------------------------------------
Mpackages/idb-bridge/src/backend-common.ts | 7-------
Mpackages/idb-bridge/src/idbtypes.ts | 9---------
Mpackages/idb-bridge/src/index.ts | 10----------
Dpackages/idb-bridge/src/util/FakeDomEvent.ts | 103-------------------------------------------------------------------------------
Dpackages/idb-bridge/src/util/canInjectKey.test.ts | 25-------------------------
Dpackages/idb-bridge/src/util/canInjectKey.ts | 58----------------------------------------------------------
Mpackages/libeufin-bank-webui/src/components/Cashouts/index.ts | 10----------
Mpackages/libeufin-bank-webui/src/hooks/account.ts | 48------------------------------------------------
Mpackages/libeufin-bank-webui/src/hooks/regional.ts | 84-------------------------------------------------------------------------------
Mpackages/libeufin-bank-webui/src/pages/OperationState/index.ts | 9---------
Mpackages/libeufin-bank-webui/src/utils.ts | 28----------------------------
Mpackages/taler-auditor-webui/src/components/menu/index.tsx | 4----
Mpackages/taler-auditor-webui/src/context/backend.ts | 11-----------
Mpackages/taler-auditor-webui/src/hooks/operational.ts | 4----
Dpackages/taler-exchange-aml-webui/src/components/ShowDefaultRules.tsx | 16----------------
Mpackages/taler-exchange-aml-webui/src/context/ui-forms.ts | 2--
Mpackages/taler-exchange-aml-webui/src/hooks/decision-request.ts | 62--------------------------------------------------------------
Mpackages/taler-exchange-aml-webui/src/hooks/decisions.ts | 50--------------------------------------------------
Mpackages/taler-exchange-aml-webui/src/hooks/server-info.ts | 45---------------------------------------------
Mpackages/taler-exchange-aml-webui/src/hooks/transfers.ts | 51+--------------------------------------------------
Mpackages/taler-exchange-aml-webui/src/pages/AccountList.tsx | 20--------------------
Dpackages/taler-exchange-aml-webui/src/utils/getTimeframesForDate.ts | 87-------------------------------------------------------------------------------
Mpackages/taler-exchange-kyc-webui/src/Routing.tsx | 9---------
Mpackages/taler-exchange-kyc-webui/src/context/settings.ts | 3---
Mpackages/taler-exchange-kyc-webui/src/context/ui-forms.ts | 2--
Dpackages/taler-exchange-kyc-webui/src/pages/NonceNotFound.tsx | 36------------------------------------
Mpackages/taler-exchange-kyc-webui/src/pages/Start.tsx | 28----------------------------
Mpackages/taler-harness/src/harness/environments.ts | 15---------------
Mpackages/taler-harness/src/harness/harness.ts | 13-------------
Dpackages/taler-harness/src/harness/sync.ts | 119-------------------------------------------------------------------------------
Mpackages/taler-harness/src/index.ts | 8--------
Mpackages/taler-harness/src/integrationtests/test-tops-aml-measures.ts | 4+---
Mpackages/taler-harness/src/integrationtests/test-tops-aml-pdf.ts | 4+---
Mpackages/taler-merchant-webui/src/api/contracts.ts | 13-------------
Mpackages/taler-merchant-webui/src/api/hooks/useOrders.ts | 13-------------
Mpackages/taler-merchant-webui/src/stores/preferences.ts | 3---
Mpackages/taler-merchant-webui/src/stores/session.ts | 2--
Mpackages/taler-merchant-webui/src/tutorial/demoData.ts | 2--
Mpackages/taler-merchant-webui/src/tutorial/tutorialData.tsx | 12------------
Mpackages/taler-merchant-webui/src/ui/Badge.tsx | 25-------------------------
Dpackages/taler-merchant-webui/src/ui/Card.tsx | 42------------------------------------------
Dpackages/taler-merchant-webui/src/ui/Table.tsx | 29-----------------------------
Mpackages/taler-merchant-webui/src/utils/runtimeValidation.ts | 11-----------
Dpackages/taler-util/src/ReserveTransaction.ts | 256-------------------------------------------------------------------------------
Dpackages/taler-util/src/aml/events.test.ts | 132-------------------------------------------------------------------------------
Mpackages/taler-util/src/aml/events.ts | 42+-----------------------------------------
Mpackages/taler-util/src/aml/reporting.ts | 4----
Mpackages/taler-util/src/bank-api-client.ts | 15++++++++-------
Mpackages/taler-util/src/bitcoin.ts | 4----
Mpackages/taler-util/src/codec.ts | 78------------------------------------------------------------------------------
Mpackages/taler-util/src/errors.ts | 19+------------------
Mpackages/taler-util/src/helpers.ts | 14--------------
Mpackages/taler-util/src/http-client/bank-integration.ts | 28+++++++++++++---------------
Mpackages/taler-util/src/http-client/bank-prepared.ts | 9---------
Mpackages/taler-util/src/http-client/bank-revenue.ts | 9---------
Mpackages/taler-util/src/http-client/bank-wire.ts | 14++++----------
Mpackages/taler-util/src/http-client/challenger.ts | 4----
Mpackages/taler-util/src/http-client/exchange-client.ts | 4----
Mpackages/taler-util/src/http-client/mailbox.ts | 14++++----------
Mpackages/taler-util/src/http-client/merchant.ts | 21---------------------
Mpackages/taler-util/src/http-client/taldir.ts | 48++++++++----------------------------------------
Mpackages/taler-util/src/http-common.ts | 94-------------------------------------------------------------------------------
Mpackages/taler-util/src/i18n.ts | 19-------------------
Mpackages/taler-util/src/iban.ts | 153-------------------------------------------------------------------------------
Mpackages/taler-util/src/index.node.ts | 1-
Mpackages/taler-util/src/index.ts | 4----
Mpackages/taler-util/src/iso-3166.ts | 70----------------------------------------------------------------------
Dpackages/taler-util/src/iso-4217.ts | 532-------------------------------------------------------------------------------
Dpackages/taler-util/src/iso-639.ts | 1246-------------------------------------------------------------------------------
Mpackages/taler-util/src/kdf.ts | 30------------------------------
Dpackages/taler-util/src/kyc-aml-utils.ts | 63---------------------------------------------------------------
Mpackages/taler-util/src/logging.ts | 4----
Mpackages/taler-util/src/operation.ts | 34----------------------------------
Mpackages/taler-util/src/payto.ts | 48++++++++++++++++--------------------------------
Mpackages/taler-util/src/sha256.ts | 90-------------------------------------------------------------------------------
Mpackages/taler-util/src/taler-crypto.ts | 62--------------------------------------------------------------
Mpackages/taler-util/src/time.ts | 25++++++++++++++-----------
Mpackages/taler-util/src/types-donau.ts | 15+--------------
Mpackages/taler-util/src/types-taler-bank-integration.ts | 27---------------------------
Mpackages/taler-util/src/types-taler-common.ts | 99-------------------------------------------------------------------------------
Mpackages/taler-util/src/types-taler-corebank.ts | 64----------------------------------------------------------------
Mpackages/taler-util/src/types-taler-directory.ts | 44++++++--------------------------------------
Mpackages/taler-util/src/types-taler-exchange.ts | 501-------------------------------------------------------------------------------
Mpackages/taler-util/src/types-taler-kyc-aml.ts | 31-------------------------------
Mpackages/taler-util/src/types-taler-mailbox.ts | 32++++----------------------------
Mpackages/taler-util/src/types-taler-merchant.ts | 418+++++++------------------------------------------------------------------------
Mpackages/taler-util/src/types-taler-prepared-transfer.ts | 116+++++++++++++++++++++++++++----------------------------------------------------
Dpackages/taler-util/src/types-taler-sync.ts | 44--------------------------------------------
Mpackages/taler-util/src/types-taler-wallet-transactions.ts | 34+---------------------------------
Mpackages/taler-util/src/types-taler-wallet.ts | 388-------------------------------------------------------------------------------
Mpackages/taler-wallet-core/src/balance.ts | 13-------------
Mpackages/taler-wallet-core/src/common.ts | 80-------------------------------------------------------------------------------
Mpackages/taler-wallet-core/src/crypto/cryptoImplementation.ts | 42------------------------------------------
Mpackages/taler-wallet-core/src/db/indexeddb/database.ts | 20--------------------
Mpackages/taler-wallet-core/src/db/indexeddb/schema.ts | 97-------------------------------------------------------------------------------
Mpackages/taler-wallet-core/src/db/sqlite/schema.ts | 5-----
Mpackages/taler-wallet-core/src/db/sqlite/transaction.ts | 11++---------
Mpackages/taler-wallet-core/src/db/timestamps.ts | 12------------
Mpackages/taler-wallet-core/src/denominations.ts | 16----------------
Mpackages/taler-wallet-core/src/exchanges.ts | 26--------------------------
Mpackages/taler-wallet-core/src/host-common.ts | 13-------------
Mpackages/taler-wallet-core/src/host.ts | 10----------
Mpackages/taler-wallet-core/src/index.ts | 1-
Mpackages/taler-wallet-core/src/instructedAmountConversion.ts | 25-------------------------
Mpackages/taler-wallet-core/src/observable-wrappers.ts | 58----------------------------------------------------------
Mpackages/taler-wallet-core/src/pay-merchant.ts | 45---------------------------------------------
Mpackages/taler-wallet-core/src/refresh.ts | 55-------------------------------------------------------
Mpackages/taler-wallet-core/src/tokenSelection.ts | 15---------------
Mpackages/taler-wallet-core/src/wallet.ts | 10----------
Mpackages/taler-wallet-core/src/withdraw.ts | 28----------------------------
Mpackages/wallet-webui/src/stores/ui.ts | 1-
Dpackages/wallet-webui/src/testing/fakes.ts | 25-------------------------
Mpackages/web-util/build.mjs | 2--
Mpackages/web-util/src/forms/fields/InputDrilldown.tsx | 5-----
Mpackages/web-util/src/hooks/index.ts | 1-
Dpackages/web-util/src/hooks/useMemoryStorage.ts | 71-----------------------------------------------------------------------
Mpackages/web-util/src/index.testing.ts | 2--
Dpackages/web-util/src/tests/mock.ts | 493-------------------------------------------------------------------------------
Dpackages/web-util/src/tests/swr.ts | 112-------------------------------------------------------------------------------
Mpackages/web-util/src/utils/route.ts | 10----------
135 files changed, 162 insertions(+), 7867 deletions(-)

diff --git a/packages/anastasis-core/src/provider-types.ts b/packages/anastasis-core/src/provider-types.ts @@ -103,17 +103,6 @@ export interface TruthUploadRequest { storage_duration_years: number; } -export interface IbanExternalAuthResponse { - method: "iban"; - answer_code: number; - details: { - challenge_amount: AmountString; - credit_iban: string; - business_name: string; - wire_transfer_subject: string; - }; -} - export interface RecoveryMetaResponse { /** * Version numbers as a string (!) are used as keys. diff --git a/packages/anastasis-core/src/reducer-types.ts b/packages/anastasis-core/src/reducer-types.ts @@ -336,14 +336,6 @@ export type AuthenticationProviderStatus = | AuthenticationProviderStatusError | AuthenticationProviderStatusOk; -export interface ReducerStateBackupUserAttributesCollecting extends ReducerStateBackup { - backup_state: BackupStates.UserAttributesCollecting; - selected_country: string; - currencies: string[]; - required_attributes: UserAttributeSpec[]; - authentication_providers: AuthenticationProviderStatusMap; -} - export interface ActionArgsEnterUserAttributes { identity_attributes: Record<string, string>; } diff --git a/packages/anastasis-webui/src/components/fields/ImageInput.tsx b/packages/anastasis-webui/src/components/fields/ImageInput.tsx @@ -1,93 +0,0 @@ -/* - This file is part of GNU Anastasis - (C) 2021-2022 Anastasis SARL - - GNU Anastasis is free software; you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Anastasis 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - GNU Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; -import emptyImage from "../../assets/empty.png"; -import { TextInputProps } from "./TextInput.js"; - -const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024; - -export function ImageInput(props: TextInputProps): VNode { - const inputRef = useRef<HTMLInputElement>(null); - useLayoutEffect(() => { - if (props.grabFocus) { - inputRef.current?.focus(); - } - }, [props.grabFocus]); - - const value = props.bind[0]; - // const [dirty, setDirty] = useState(false) - const image = useRef<HTMLInputElement>(null); - const [sizeError, setSizeError] = useState(false); - function onChange(v: string): void { - // setDirty(true); - props.bind[1](v); - } - return ( - <div class="field"> - <label class="label"> - {props.label} - {props.tooltip && ( - <span class="icon has-tooltip-right" data-tooltip={props.tooltip}> - <i class="mdi mdi-information" /> - </span> - )} - </label> - <div class="control"> - <img - src={!value ? emptyImage : value} - style={{ width: 200, height: 200 }} - onClick={() => image.current?.click()} - /> - <input - ref={image} - style={{ display: "none" }} - type="file" - name={String(name)} - onChange={(e) => { - const f: FileList | null = e.currentTarget.files; - if (!f || f.length != 1) { - return onChange(emptyImage); - } - if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) { - setSizeError(true); - return onChange(emptyImage); - } - setSizeError(false); - return f[0].arrayBuffer().then((b) => { - const b64 = btoa( - new Uint8Array(b).reduce( - (data, byte) => data + String.fromCharCode(byte), - "", - ), - ); - return onChange(`data:${f[0].type};base64,${b64}` as any); - }); - }} - /> - {props.error && <p class="help is-danger">{props.error}</p>} - {sizeError && ( - <p class="help is-danger">Image should be smaller than 1 MB</p> - )} - </div> - </div> - ); -} diff --git a/packages/anastasis-webui/src/components/menu/LangSelector.tsx b/packages/anastasis-webui/src/components/menu/LangSelector.tsx @@ -1,92 +0,0 @@ -/* - This file is part of GNU Anastasis - (C) 2021-2022 Anastasis SARL - - GNU Anastasis is free software; you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Anastasis 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - GNU Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, VNode } from "preact"; -import { useState } from "preact/hooks"; -import langIcon from "../../assets/icons/languageicon.svg"; -import { useTranslationContext } from "../../context/translation.js"; -import { strings as messages } from "../../i18n/strings.js"; - -type LangsNames = { - [P in keyof typeof messages]: string; -}; - -const names: LangsNames = { - es: "Español [es]", - en: "English [en]", - fr: "Français [fr]", - de: "Deutsch [de]", - sv: "Svenska [sv]", - it: "Italiano [it]", -}; - -function getLangName(s: keyof LangsNames | string): string { - if (names[s]) return names[s]; - return String(s); -} - -export function LangSelector(): VNode { - const [updatingLang, setUpdatingLang] = useState(false); - const { lang, changeLanguage } = useTranslationContext(); - - return ( - <div class="dropdown is-active "> - <div class="dropdown-trigger"> - <button - class="button has-tooltip-left" - data-tooltip="change language selection" - aria-haspopup="true" - aria-controls="dropdown-menu" - onClick={() => setUpdatingLang(!updatingLang)} - > - <div class="icon is-small is-left"> - <img src={langIcon} /> - </div> - <span>{getLangName(lang)}</span> - <div class="icon is-right"> - <i class="mdi mdi-chevron-down" /> - </div> - </button> - </div> - {updatingLang && ( - <div class="dropdown-menu" id="dropdown-menu" role="menu"> - <div class="dropdown-content"> - {Object.keys(messages) - .filter((l) => l !== lang) - .map((l) => ( - <a - key={l} - class="dropdown-item" - value={l} - onClick={() => { - changeLanguage(l); - setUpdatingLang(false); - }} - > - {getLangName(l)} - </a> - ))} - </div> - </div> - )} - </div> - ); -} diff --git a/packages/anastasis-webui/src/components/menu/index.tsx b/packages/anastasis-webui/src/components/menu/index.tsx @@ -64,72 +64,10 @@ export function Menu({ title }: MenuProps): VNode { ); } -interface NotYetReadyAppMenuProps { - title: string; - onLogout?: () => void; -} - -interface NotifProps { - notification?: Notification; -} -export function NotificationCard({ - notification: n, -}: NotifProps): VNode | null { - if (!n) return null; - return ( - <div class="notification"> - <div class="columns is-vcentered"> - <div class="column is-12"> - <article - class={ - n.type === "ERROR" - ? "message is-danger" - : n.type === "WARN" - ? "message is-warning" - : "message is-info" - } - > - <div class="message-header"> - <p>{n.message}</p> - </div> - {n.description && <div class="message-body">{n.description}</div>} - </article> - </div> - </div> - </div> - ); -} - -export function NotYetReadyAppMenu({ - onLogout, - title, -}: NotYetReadyAppMenuProps): VNode { - const [mobileOpen, setMobileOpen] = useState(false); - - useEffect(() => { - document.title = `Taler Backoffice: ${title}`; - }, [title]); - - return ( - <div - class="has-aside-mobile-expanded" - // class={mobileOpen ? "has-aside-mobile-expanded" : ""} - onClick={() => setMobileOpen(false)} - > - <NavigationBar - onMobileMenu={() => setMobileOpen(!mobileOpen)} - title={title} - /> - {onLogout && <Sidebar mobile={mobileOpen} />} - </div> - ); -} - export interface Notification { message: string; description?: string | VNode; type: MessageType; } -export type ValueOrFunction<T> = T | ((p: T) => T); export type MessageType = "INFO" | "WARN" | "ERROR" | "SUCCESS"; diff --git a/packages/anastasis-webui/src/hooks/index.ts b/packages/anastasis-webui/src/hooks/index.ts @@ -1,74 +0,0 @@ -/* - This file is part of GNU Anastasis - (C) 2021-2022 Anastasis SARL - - GNU Anastasis is free software; you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Anastasis 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - GNU Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { StateUpdater } from "preact/hooks"; -import { useLocalStorage, useNotNullLocalStorage } from "./useLocalStorage.js"; - -export type ValueOrFunction<T> = T | ((p: T) => T); - -const calculateRootPath = () => { - const rootPath = - typeof window !== "undefined" - ? window.location.origin + window.location.pathname - : "/"; - return rootPath; -}; - -export function useBackendURL( - url?: string, -): [string, boolean, StateUpdater<string>, () => void] { - const [value, setter] = useNotNullLocalStorage( - "backend-url", - url || calculateRootPath(), - ); - const [triedToLog, setTriedToLog] = useLocalStorage("tried-login"); - - const checkedSetter = (v: ValueOrFunction<string>) => { - setTriedToLog("yes"); - return setter((p) => (v instanceof Function ? v(p) : v).replace(/\/$/, "")); - }; - - const resetBackend = () => { - setTriedToLog(undefined); - }; - return [value, !!triedToLog, checkedSetter, resetBackend]; -} - -export function useBackendDefaultToken(): [ - string | undefined, - StateUpdater<string | undefined>, -] { - return useLocalStorage("backend-token"); -} - -export function useBackendInstanceToken( - id: string, -): [string | undefined, StateUpdater<string | undefined>] { - const [token, setToken] = useLocalStorage(`backend-token-${id}`); - const [defaultToken, defaultSetToken] = useBackendDefaultToken(); - - // instance named 'default' use the default token - if (id === "default") { - return [defaultToken, defaultSetToken]; - } - - return [token, setToken]; -} diff --git a/packages/anastasis-webui/src/hooks/useLocalStorage.ts b/packages/anastasis-webui/src/hooks/useLocalStorage.ts @@ -21,37 +21,6 @@ import { StateUpdater, useState } from "preact/hooks"; -export function useLocalStorage( - key: string, - initialValue?: string, -): [string | undefined, StateUpdater<string | undefined>] { - const [storedValue, setStoredValue] = useState<string | undefined>( - (): string | undefined => { - return typeof window !== "undefined" - ? window.localStorage.getItem(key) || initialValue - : initialValue; - }, - ); - - const setValue = ( - value?: string | ((val?: string) => string | undefined), - ): void => { - setStoredValue((p) => { - const toStore = value instanceof Function ? value(p) : value; - if (typeof window !== "undefined") { - if (!toStore) { - window.localStorage.removeItem(key); - } else { - window.localStorage.setItem(key, toStore); - } - } - return toStore; - }); - }; - - return [storedValue, setValue]; -} - //TODO: merge with the above function export function useNotNullLocalStorage( key: string, diff --git a/packages/challenger-webui/src/context/preferences.ts b/packages/challenger-webui/src/context/preferences.ts @@ -1,82 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022-2024 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 { - Codec, - TranslatedString, - buildCodecForObject, - codecForBoolean, -} from "@gnu-taler/taler-util"; -import { - buildStorageKey, - useLocalStorage, - useTranslationContext, -} from "@gnu-taler/web-util/browser"; - -interface Preferences { - showChallangeSetup: boolean; -} - -export const codecForPreferences = (): Codec<Preferences> => - buildCodecForObject<Preferences>() - .allowExtra() - .property("showChallangeSetup", codecForBoolean()) - .build("Preferences"); - -const defaultPreferences: Preferences = { - showChallangeSetup: false, -}; - -const PREFERENCES_KEY = buildStorageKey( - "challenger-preferences", - codecForPreferences(), -); -/** - * User preferences. - * - * @returns tuple of [state, update()] - */ -export function usePreferences(): [ - Readonly<Preferences>, - <T extends keyof Preferences>(key: T, value: Preferences[T]) => void, -] { - const { value, update } = useLocalStorage( - PREFERENCES_KEY, - defaultPreferences, - ); - - function updateField<T extends keyof Preferences>(k: T, v: Preferences[T]) { - const newValue = { ...value, [k]: v }; - update(newValue); - } - return [value, updateField]; -} - -export function getAllBooleanPreferences(): Array<keyof Preferences> { - return ["showChallangeSetup"]; -} - -export function getLabelForPreferences( - k: keyof Preferences, - i18n: ReturnType<typeof useTranslationContext>["i18n"], -): TranslatedString { - switch (k) { - case "showChallangeSetup": - // Translators: Developer preference that exposes Challenger's manual - // OAuth session-setup screen; it is not part of the normal user flow. - return i18n.str`Show challenger setup screen`; - } -} diff --git a/packages/challenger-webui/src/context/settings.ts b/packages/challenger-webui/src/context/settings.ts @@ -15,7 +15,6 @@ */ import { ComponentChildren, createContext, h, VNode } from "preact"; -import { useContext } from "preact/hooks"; import { ChallengerUiSettings } from "../settings.js"; /** @@ -28,8 +27,6 @@ export type Type = ChallengerUiSettings; const initial: ChallengerUiSettings = {}; const Context = createContext<Type>(initial); -export const useSettingsContext = (): Type => useContext(Context); - export const SettingsProvider = ({ children, value, diff --git a/packages/challenger-webui/src/hooks/session.ts b/packages/challenger-webui/src/hooks/session.ts @@ -39,14 +39,6 @@ export type SessionId = { state?: string; }; -export type LastChallengeResponse = { - sendCodeLeft: number; - changeTargetLeft: number; - checkPinLeft: number; - nextSend: AbsoluteTime; - transmitted: boolean; -}; - interface LastAddress { address: Record<string, string>; type: string; diff --git a/packages/challenger-webui/src/pages/AskChallenge.tsx b/packages/challenger-webui/src/pages/AskChallenge.tsx @@ -675,25 +675,12 @@ export function challengeFailureMessage( } } -export function undefinedIfEmpty<T extends object>(obj: T): T | undefined { - return Object.keys(obj).some( - (k) => (obj as Record<string, T>)[k] !== undefined, - ) - ? obj - : undefined; -} - export const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; export const INT_PHONE_REGEX = /^\+?[1-9]\d{6,14}$/; // E.164 International Phone Number -export const US_PHONE_REGEX = - /^(\+\d{1,2}\s?)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/; -export const AR_PHONE_REGEX = - /^(?:(?:00|\+)?549?)?\s?(?:[23]\d{2})?\s?(?:\d{4}[-.\s]?\d{4})$/; export const PHONE_REGEX = INT_PHONE_REGEX; export const CONTACT_REGEX = /.*/; -export const ZIPCODE_REGEX = /.*/; export const ADDR_LINES_REGEX = /.*/; export function getLocalizedRestrictionHint( diff --git a/packages/challenger-webui/src/pages/CallengeCompleted.tsx b/packages/challenger-webui/src/pages/CallengeCompleted.tsx @@ -177,9 +177,6 @@ export function ChallengeCompleted({ session }: { session: SessionId }): VNode { ); } -// Keep the old export for downstream imports while correcting the name. -export const CallengeCompleted = ChallengeCompleted; - export function safeRedirectURL(value: string | undefined): string | undefined { if (!value) return undefined; try { diff --git a/packages/challenger-webui/src/pages/MissingParams.tsx b/packages/challenger-webui/src/pages/MissingParams.tsx @@ -1,20 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022-2024 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 { VNode, h } from "preact"; - -export function MissingParams(): VNode { - return <div>missing params: {window.location.href}</div>; -} diff --git a/packages/challenger-webui/src/pages/NonceNotFound.tsx b/packages/challenger-webui/src/pages/NonceNotFound.tsx @@ -1,42 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022-2024 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 { useTranslationContext } from "@gnu-taler/web-util/browser"; -import { Fragment, VNode, h } from "preact"; - -export function NonceNotFound(): VNode { - const { i18n } = useTranslationContext(); - // Translators: Error heading for a malformed verification URL or a URL whose - // session identifier Challenger no longer recognizes. - const invalidUrlTitle = i18n.str`The URL is wrong`; - // Translators: Possible explanation shown below the invalid verification-URL - // heading. - const expiredUrlDescription = i18n.str`Maybe the validation check expired.`; - - return ( - <Fragment> - <div class="isolate bg-white px-6 py-12"> - <div class="mx-auto max-w-2xl text-center"> - <h2 class="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl"> - {invalidUrlTitle} - </h2> - <p class="mt-2 text-lg leading-8 text-gray-600"> - {expiredUrlDescription} - </p> - </div> - </div> - </Fragment> - ); -} diff --git a/packages/idb-bridge/src/MemoryBackend.ts b/packages/idb-bridge/src/MemoryBackend.ts @@ -14,50 +14,6 @@ permissions and limitations under the License. */ -import { IDBValidKey } from "./idbtypes.js"; - -type Key = IDBValidKey; -type Value = unknown; - -export interface ObjectStoreDump { - name: string; - keyGenerator: number; - records: ObjectStoreRecord[]; -} - -export interface DatabaseDump { - schema: Schema; - objectStores: { [name: string]: ObjectStoreDump }; -} - -export interface MemoryBackendDump { - databases: { [name: string]: DatabaseDump }; -} - -export interface ObjectStoreProperties { - keyPath: string | string[] | null; - autoIncrement: boolean; - indexes: { [nameame: string]: IndexProperties }; -} - -export interface IndexProperties { - keyPath: string | string[]; - multiEntry: boolean; - unique: boolean; -} - -export interface Schema { - databaseName: string; - databaseVersion: number; - objectStores: { [name: string]: ObjectStoreProperties }; -} - -/** @public */ -export interface ObjectStoreRecord { - primaryKey: Key; - value: Value; -} - export interface AccessStats { primitiveStatements: number; writeTransactions: number; diff --git a/packages/idb-bridge/src/backend-common.ts b/packages/idb-bridge/src/backend-common.ts @@ -20,10 +20,3 @@ export class AsyncCondition { this._resolveWaitPromise = op.resolve; } } - -export enum TransactionLevel { - None = 0, - Read = 1, - Write = 2, - VersionChange = 3, -} diff --git a/packages/idb-bridge/src/idbtypes.ts b/packages/idb-bridge/src/idbtypes.ts @@ -206,15 +206,6 @@ export interface IDBObjectStoreParameters { /** * @public */ -export interface EventInit { - bubbles?: boolean; - cancelable?: boolean; - composed?: boolean; -} - -/** - * @public - */ export interface IDBArrayKey extends Array<IDBValidKey> {} /** diff --git a/packages/idb-bridge/src/index.ts b/packages/idb-bridge/src/index.ts @@ -23,12 +23,6 @@ import { RequestObj, } from "./bridge-idb.js"; import { Event } from "./idbtypes.js"; -import { - DatabaseDump, - MemoryBackendDump, - ObjectStoreDump, - ObjectStoreRecord, -} from "./MemoryBackend.js"; import { Listener } from "./util/FakeEventTarget.js"; export * from "./sqlite3-interface.js"; @@ -53,14 +47,10 @@ export { export type { Backend, DatabaseConnection, - DatabaseDump, DatabaseList, DatabaseTransaction, Event, Listener, - MemoryBackendDump, - ObjectStoreDump, - ObjectStoreRecord, RecordGetResponse, RecordStoreRequest, RecordStoreResponse, diff --git a/packages/idb-bridge/src/util/FakeDomEvent.ts b/packages/idb-bridge/src/util/FakeDomEvent.ts @@ -1,103 +0,0 @@ -/* - Copyright 2017 Jeremy Scheff - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - or implied. See the License for the specific language governing - permissions and limitations under the License. -*/ - -import FakeEventTarget from "./FakeEventTarget.js"; -import { Event, EventTarget } from "../idbtypes.js"; - -/** @public */ -export type EventType = - | "abort" - | "blocked" - | "complete" - | "error" - | "success" - | "upgradeneeded" - | "versionchange"; - -export class FakeDomEvent implements Event { - public eventPath: FakeEventTarget[] = []; - public type: EventType; - - public readonly NONE = 0; - public readonly CAPTURING_PHASE = 1; - public readonly AT_TARGET = 2; - public readonly BUBBLING_PHASE = 3; - - // Flags - public propagationStopped = false; - public immediatePropagationStopped = false; - public canceled = false; - public initialized = true; - public dispatched = false; - - public target: FakeEventTarget | null = null; - public currentTarget: FakeEventTarget | null = null; - - public eventPhase: 0 | 1 | 2 | 3 = 0; - - public defaultPrevented = false; - - public isTrusted = false; - public timeStamp = Date.now(); - - public bubbles: boolean; - public cancelable: boolean; - - constructor( - type: EventType, - eventInitDict: { bubbles?: boolean; cancelable?: boolean } = {}, - ) { - this.type = type; - - this.bubbles = - eventInitDict.bubbles !== undefined ? eventInitDict.bubbles : false; - this.cancelable = - eventInitDict.cancelable !== undefined ? eventInitDict.cancelable : false; - } - cancelBubble: boolean = false; - composed: boolean = false; - returnValue: boolean = false; - get srcElement(): EventTarget | null { - return this.target; - } - composedPath(): EventTarget[] { - throw new Error("Method not implemented."); - } - initEvent( - type: string, - bubbles?: boolean | undefined, - cancelable?: boolean | undefined, - ): void { - throw new Error("Method not implemented."); - } - - public preventDefault() { - if (this.cancelable) { - this.canceled = true; - } - } - - public stopPropagation() { - this.propagationStopped = true; - } - - public stopImmediatePropagation() { - this.propagationStopped = true; - this.immediatePropagationStopped = true; - } -} - -export default FakeDomEvent; diff --git a/packages/idb-bridge/src/util/canInjectKey.test.ts b/packages/idb-bridge/src/util/canInjectKey.test.ts @@ -1,25 +0,0 @@ -/* - Copyright 2017 Jeremy Scheff - Copyright 20201 Taler Systems SA - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - or implied. See the License for the specific language governing - permissions and limitations under the License. -*/ - -import { test } from "node:test"; -import assert from "node:assert"; -import { canInjectKey } from "./canInjectKey.js"; - -test("canInjectKey", (t) => { - assert.strictEqual(canInjectKey("foo", null), false); - assert.ok(canInjectKey("foo", {})); -}); diff --git a/packages/idb-bridge/src/util/canInjectKey.ts b/packages/idb-bridge/src/util/canInjectKey.ts @@ -1,58 +0,0 @@ -/* - Copyright 2017 Jeremy Scheff - Copyright 20201 Taler Systems SA - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - or implied. See the License for the specific language governing - permissions and limitations under the License. -*/ - -import { IDBKeyPath } from "../idbtypes.js"; - -/** - * Check that a key could be injected into a value. - * - * https://www.w3.org/TR/IndexedDB/#check-that-a-key-could-be-injected-into-a-value - */ -export function canInjectKey( - keyPath: IDBKeyPath | IDBKeyPath[], - value: any, -): boolean { - if (Array.isArray(keyPath)) { - throw new Error( - "The key paths used in this section are always strings and never sequences, since it is not possible to create a object store which has a key generator and also has a key path that is a sequence.", - ); - } - - const identifiers = keyPath.split("."); - if (identifiers.length === 0) { - throw new Error("Assert: identifiers is not empty"); - } - identifiers.pop(); - - for (const identifier of identifiers) { - if ( - value === null || - (typeof value !== "object" && !Array.isArray(value)) - ) { - return false; - } - - const hop = value.hasOwnProperty(identifier); - if (!hop) { - return true; - } - - value = value[identifier]; - } - - return value !== null && (typeof value === "object" || Array.isArray(value)); -} diff --git a/packages/libeufin-bank-webui/src/components/Cashouts/index.ts b/packages/libeufin-bank-webui/src/components/Cashouts/index.ts @@ -15,8 +15,6 @@ */ import { - AbsoluteTime, - AmountJson, TalerCoreBankErrorsByMethod, TalerCorebankApi, TalerError, @@ -72,14 +70,6 @@ export namespace State { } } -export interface Transaction { - negative: boolean; - counterpart: string; - when: AbsoluteTime; - amount: AmountJson | undefined; - subject: string; -} - const viewMapping: utils.StateViewMap<State> = { loading: Loading, "loading-error": RetryableError, diff --git a/packages/libeufin-bank-webui/src/hooks/account.ts b/packages/libeufin-bank-webui/src/hooks/account.ts @@ -40,11 +40,6 @@ import _useSWR, { mutate, SWRHook } from "swr"; import { PAGINATED_LIST_REQUEST } from "../utils.js"; const useSWR = _useSWR as unknown as SWRHook; -export interface InstanceTemplateFilter { - // FIXME: add filter to the template list - position?: string; -} - export function revalidateAccountDetails() { return mutate( (key) => Array.isArray(key) && key[key.length - 1] === "getAccount", @@ -116,49 +111,6 @@ export function useWithdrawalDetails(wid: string | undefined) { return result; } -export function revalidateTransactionDetails() { - return mutate( - (key) => Array.isArray(key) && key[key.length - 1] === "getTransactionById", - undefined, - { revalidate: true }, - ); -} -export function useTransactionDetails(account: string, tid: number) { - const { state: credentials } = useSessionState(); - const token = - credentials.status !== "loggedIn" ? undefined : credentials.token; - const { - lib: { bank: api }, - } = useBankCoreApiContext(); - - async function fetcher([username, token, txid]: [ - string, - AccessToken, - number, - ]) { - return await api.getTransactionById({ username, token }, txid); - } - - const { data, error } = useSWR< - TalerCoreBankResultByMethod<"getTransactionById">, - TalerHttpError - >([account, token, tid, "getTransactionById"], fetcher, { - refreshInterval: 0, - refreshWhenHidden: false, - revalidateOnFocus: false, - revalidateOnReconnect: false, - refreshWhenOffline: false, - errorRetryCount: 0, - errorRetryInterval: 1, - shouldRetryOnError: false, - keepPreviousData: true, - }); - - if (data) return data; - if (error) return error; - return undefined; -} - export async function revalidatePublicAccounts() { return mutate( (key) => Array.isArray(key) && key[key.length - 1] === "getPublicAccounts", diff --git a/packages/libeufin-bank-webui/src/hooks/regional.ts b/packages/libeufin-bank-webui/src/hooks/regional.ts @@ -271,18 +271,6 @@ export function useCashoutEstimatorForClass( ); } -export function useCashinEstimatorByUser( - username: string, -): ConversionEstimators { - const { - lib: { conversionForUser }, - } = useBankCoreApiContext(); - return useConversionEstimatorsWithTheBackend( - conversionForUser(username), - "cashin", - ); -} - export function useCashoutEstimatorByUser( username: string, ): ConversionEstimators { @@ -384,72 +372,6 @@ async function mapWithConcurrency<Input, Output>( ); return output; } -export function revalidateOnePendingCashouts() { - return mutate( - (key) => - Array.isArray(key) && key[key.length - 1] === "useOnePendingCashouts", - undefined, - { revalidate: true }, - ); -} -export function useOnePendingCashouts(account: string) { - const { state: credentials } = useSessionState(); - const { - lib: { bank: api }, - config, - } = useBankCoreApiContext(); - const token = - credentials.status !== "loggedIn" ? undefined : credentials.token; - - async function fetcher([username, token]: [string, AccessToken]) { - const list = await api.getAccountCashouts({ username, token }); - if (list.type !== "ok") { - return list; - } - const pendingCashout = - list.body.cashouts.length > 0 ? list.body.cashouts[0] : undefined; - if (!pendingCashout) return opFixedSuccess(dummyHttpResponse, undefined); - const cashoutInfo = await api.getCashoutById( - { username, token }, - pendingCashout.cashout_id, - ); - if (cashoutInfo.type !== "ok") { - return cashoutInfo; - } - return opFixedSuccess(dummyHttpResponse, { - ...cashoutInfo.body, - id: pendingCashout.cashout_id, - }); - } - - const { data, error } = useSWR< - | OperationOk<CashoutWithId | undefined> - | TalerCoreBankErrorsByMethod<"getAccountCashouts"> - | TalerCoreBankErrorsByMethod<"getCashoutById">, - TalerHttpError - >( - !config.allow_conversion - ? undefined - : [account, token, "useOnePendingCashouts"], - fetcher, - { - refreshInterval: 0, - refreshWhenHidden: false, - revalidateOnFocus: false, - revalidateOnReconnect: false, - refreshWhenOffline: false, - errorRetryCount: 0, - errorRetryInterval: 1, - shouldRetryOnError: false, - keepPreviousData: true, - }, - ); - - if (data) return data; - if (error) return error; - return undefined; -} - export function revalidateCashouts() { return mutate( (key) => Array.isArray(key) && key[key.length - 1] === "useCashouts", @@ -571,12 +493,6 @@ export function useCashoutDetails(cashoutId: number | undefined) { if (error) return error; return undefined; } -export type MonitorMetrics = { - lastHour: TalerCoreBankResultByMethod<"getMonitor">; - lastDay: TalerCoreBankResultByMethod<"getMonitor">; - lastMonth: TalerCoreBankResultByMethod<"getMonitor">; -}; - export type LastMonitor = { current: TalerCoreBankResultByMethod<"getMonitor">; previous: TalerCoreBankResultByMethod<"getMonitor">; diff --git a/packages/libeufin-bank-webui/src/pages/OperationState/index.ts b/packages/libeufin-bank-webui/src/pages/OperationState/index.ts @@ -15,7 +15,6 @@ */ import { - AbsoluteTime, AmountJson, TalerCoreBankErrorsByMethod, TalerError, @@ -147,14 +146,6 @@ export namespace State { } } -export interface Transaction { - negative: boolean; - counterpart: string; - when: AbsoluteTime; - amount: AmountJson | undefined; - subject: string; -} - const viewMapping: utils.StateViewMap<State> = { loading: Loading, failed: FailedView, diff --git a/packages/libeufin-bank-webui/src/utils.ts b/packages/libeufin-bank-webui/src/utils.ts @@ -42,24 +42,6 @@ export function undefinedIfEmpty<T extends object>(obj: T): T | undefined { : undefined; } -export type PartialButDefined<T> = { - [P in keyof T]: T[P] | undefined; -}; - -/** - * every non-map field can be undefined - */ -export type WithIntermediate<Type> = { - [prop in keyof Type]: Type[prop] extends PaytoString - ? Type[prop] | undefined - : Type[prop] extends AmountString - ? Type[prop] | undefined - : Type[prop] extends TranslatedString - ? Type[prop] | undefined - : Type[prop] extends object - ? WithIntermediate<Type[prop]> - : Type[prop] | undefined; -}; export type RecursivePartial<Type> = { [P in keyof Type]?: Type[P] extends (infer U)[] ? RecursivePartial<U>[] @@ -87,16 +69,6 @@ export enum TanChannel { SMS = "sms", EMAIL = "email", } -export enum CashoutStatus { - // The payment was initiated after a valid - // TAN was received by the bank. - CONFIRMED = "confirmed", - - // The cashout was created and now waits - // for the TAN by the author. - PENDING = "pending", -} - export const PAGINATED_LIST_SIZE = 20; // when doing paginated request, ask for one more // and use it to know if there are more to request diff --git a/packages/taler-auditor-webui/src/components/menu/index.tsx b/packages/taler-auditor-webui/src/components/menu/index.tsx @@ -61,7 +61,3 @@ export function NotConnectedAppMenu({ title }: { title: string }): VNode { }, [title]); return <NavigationBar title={title} onMobileMenu={() => undefined} withSidebar={false} />; } - -export function NotYetReadyAppMenu({ title }: { title: string; onShowSettings: () => void }): VNode { - return <NotConnectedAppMenu title={title} />; -} diff --git a/packages/taler-auditor-webui/src/context/backend.ts b/packages/taler-auditor-webui/src/context/backend.ts @@ -51,14 +51,3 @@ export const BackendContextProvider = ({ export const useBackendContext = (): BackendContextType => useContext(BackendContext); - -interface BackendTokenType { - token: string; -} - -const BackendTokenContext = createContext<BackendTokenType>({} as any); - -export const BackendTokenContextProvider = BackendTokenContext.Provider; - -export const useBackendTokenContext = (): BackendTokenType => - useContext(BackendTokenContext); diff --git a/packages/taler-auditor-webui/src/hooks/operational.ts b/packages/taler-auditor-webui/src/hooks/operational.ts @@ -70,7 +70,3 @@ export function useOperationData( } return { loading: true }; } - -export interface EntityAPI { - updateEntity: (id: string) => Promise<void>; -} diff --git a/packages/taler-exchange-aml-webui/src/components/ShowDefaultRules.tsx b/packages/taler-exchange-aml-webui/src/components/ShowDefaultRules.tsx @@ -1,16 +0,0 @@ -import { KycRule } from "@gnu-taler/taler-util"; -import { useTranslationContext } from "@gnu-taler/web-util/browser"; -import { Fragment, h, VNode } from "preact"; -import { RulesInfo } from "./RulesInfo.js"; - -export function ShowDefaultRules({ rules }: { rules: KycRule[] }): VNode { - const { i18n } = useTranslationContext(); - return ( - <Fragment> - <h1 class="text-base font-semibold leading-6 text-black"> - <i18n.Translate>Default rules</i18n.Translate> - </h1> - <RulesInfo rules={rules} /> - </Fragment> - ); -} diff --git a/packages/taler-exchange-aml-webui/src/context/ui-forms.ts b/packages/taler-exchange-aml-webui/src/context/ui-forms.ts @@ -34,8 +34,6 @@ const defaultForms: Type = { }; const Context = createContext<Type>(defaultForms); -export type BaseForm = Record<string, unknown>; - export const useUiFormsContext = (): Type => useContext(Context); export function builtInUiForms( diff --git a/packages/taler-exchange-aml-webui/src/hooks/decision-request.ts b/packages/taler-exchange-aml-webui/src/hooks/decision-request.ts @@ -16,24 +16,11 @@ import { AbsoluteTime, - buildCodecForObject, - Codec, - codecForAbsoluteTime, - codecForAny, - codecForBoolean, - codecForKycRules, - codecForList, - codecForMap, - codecForNumber, - codecForString, - codecOptional, - codecOptionalDefault, KycRule, MeasureInformation, TalerExchangeApi, } from "@gnu-taler/taler-util"; import { FormErrors } from "@gnu-taler/web-util/browser"; -import { BUILT_IN_SKIP_CHECK } from "../utils/measure-check.js"; import { ComponentChildren, createContext, h, VNode } from "preact"; import { useContext, useRef, useState } from "preact/hooks"; export interface AccountAttributes { @@ -119,55 +106,6 @@ export interface DecisionRequest { rules_reviewed?: boolean; } -export const codecForMeasure = (): Codec<MeasureInformation> => - buildCodecForObject<MeasureInformation>() - .property( - "check_name", - codecOptionalDefault(codecForString(), BUILT_IN_SKIP_CHECK), - ) - .property("prog_name", codecOptional(codecForString())) - .property("context", codecOptional(codecForMap(codecForAny()))) - .build("MeasureInformation"); - -export const codecForAccountAttributes = (): Codec<AccountAttributes> => - buildCodecForObject<AccountAttributes>() - .property("expiration", codecOptional(codecForAbsoluteTime)) - .property("formId", codecOptional(codecForString())) - .property("formVersion", codecForNumber()) - .property("formSalt", codecOptional(codecForString())) - .property("data", codecForAny()) - .property("errors", codecOptional(codecForAny())) - .build("AccountAttributes"); - -export const codecForDecisionRequest = (): Codec<DecisionRequest> => - buildCodecForObject<DecisionRequest>() - .property("original", codecOptional(codecForAny())) - .property("rules", codecOptional(codecForList(codecForKycRules()))) - .property("deadline", codecOptional(codecForAbsoluteTime)) - .property("properties", codecOptional(codecForMap(codecForAny()))) - .property("properties_errors", codecOptional(codecForAny())) - .property("attributes", codecOptional(codecForAccountAttributes())) - .property("custom_properties", codecOptional(codecForMap(codecForString()))) - .property("justification", codecOptional(codecForString())) - .property("accountName", codecOptional(codecForString())) - .property("custom_events", codecOptional(codecForList(codecForString()))) - .property("custom_measures", codecOptional(codecForMap(codecForMeasure()))) - .property( - "triggering_events", - codecOptional(codecForList(codecForString())), - ) - .property("keep_investigating", codecOptional(codecForBoolean())) - .property("new_measures", codecOptional(codecForList(codecForString()))) - .property("measures_and", codecOptional(codecForBoolean())) - .property("onExpire_measure", codecOptional(codecForString())) - .property( - "property_overrides", - codecOptional(codecForList(codecForString())), - ) - .property("events_overridden", codecOptional(codecForBoolean())) - .property("rules_reviewed", codecOptional(codecForBoolean())) - .build("DecisionRequest"); - const DECISION_REQUEST_EMPTY: DecisionRequest = { original: undefined, deadline: undefined, diff --git a/packages/taler-exchange-aml-webui/src/hooks/decisions.ts b/packages/taler-exchange-aml-webui/src/hooks/decisions.ts @@ -115,56 +115,6 @@ export function useAmlAccounts({ * @param args * @returns */ -export function useCurrentDecisions({ - investigated, -}: { - investigated?: boolean; -} = {}) { - const officer = useOfficer(); - const session = officer.state === "ready" ? officer.session : undefined; - const { - lib: { exchange: api }, - } = useExchangeApiContext(); - - const [pointer, updatePointer] = useListPointer( - (row: AmlDecision) => String(row.rowid), - String(investigated ?? "all"), - ); - - async function fetcher([officer, offset, investigation]: [ - OfficerSession, - ListPointer, - boolean | undefined, - ]) { - return await api.getAmlDecisions(officer, { - order: offset.order, - offset: offset.id, - active: true, - investigation, - limit: PAGINATED_LIST_REQUEST, - }); - } - - const { data, error } = useSWR< - TalerExchangeResultByMethod2<"getAmlDecisions">, - TalerHttpError - >( - !session ? undefined : [session, pointer, investigated, "getAmlDecisions"], - fetcher, - ); - - if (error) return error; - if (data === undefined) return undefined; - if (data.type !== "ok") return data; - - return buildPaginatedResult( - data.body.records, - pointer, - updatePointer, - PAGINATED_LIST_REQUEST, - ); -} - export function revalidateAccountDecisions() { return mutate( (key) => Array.isArray(key) && key[key.length - 1] === "getAmlDecisions", diff --git a/packages/taler-exchange-aml-webui/src/hooks/server-info.ts b/packages/taler-exchange-aml-webui/src/hooks/server-info.ts @@ -14,11 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ import { - AbsoluteTime, - CounterResultByEventName, - EventReporting_VQF_queries, fetchTopsInfoFromServer, - fetchVqfInfoFromServer, OfficerSession, OperationOk, opFixedSuccess, @@ -28,7 +24,6 @@ import { // FIX default import https://github.com/microsoft/TypeScript/issues/49189 import { dummyHttpResponse } from "@gnu-taler/taler-util/http"; import { useExchangeApiContext } from "@gnu-taler/web-util/browser"; -import { endOfYear, setYear, startOfYear } from "date-fns"; import _useSWR, { mutate, SWRHook } from "swr"; import { useOfficer } from "./officer.js"; const useSWR = _useSWR as unknown as SWRHook; @@ -151,43 +146,3 @@ export function revalidateTopsServerStatistics() { { revalidate: true }, ); } - -export function useVqfServerStatistics(year: number) { - const officer = useOfficer(); - const session = officer.state === "ready" ? officer.session : undefined; - - const { - unthrottledApi: { exchange: api }, - } = useExchangeApiContext(); - - async function fetcher([officer, year]: [OfficerSession, number, string]) { - const date = setYear(new Date(), year); - const jan_1st = AbsoluteTime.fromMilliseconds(startOfYear(date).getTime()); - const dec_31st = AbsoluteTime.fromMilliseconds(endOfYear(date).getTime()); - - const final = await fetchVqfInfoFromServer(api, officer, jan_1st, dec_31st); - - return opFixedSuccess(dummyHttpResponse, final); - } - - const { data, error } = useSWR< - OperationOk< - CounterResultByEventName<ReturnType<typeof EventReporting_VQF_queries>> - >, - TalerHttpError - >(!session ? undefined : [session, year, "getVqfStatistics"], fetcher, { - refreshInterval: 0, - refreshWhenHidden: false, - revalidateOnFocus: false, - revalidateOnReconnect: false, - refreshWhenOffline: false, - errorRetryCount: 0, - errorRetryInterval: 1, - shouldRetryOnError: false, - keepPreviousData: true, - }); - - if (data) return data; - if (error) return error; - return undefined; -} diff --git a/packages/taler-exchange-aml-webui/src/hooks/transfers.ts b/packages/taler-exchange-aml-webui/src/hooks/transfers.ts @@ -30,7 +30,7 @@ import { useExchangeApiContext, useListPointer, } from "@gnu-taler/web-util/browser"; -import _useSWR, { mutate, SWRHook } from "swr"; +import _useSWR, { SWRHook } from "swr"; import { useOfficer } from "./officer.js"; const useSWR = _useSWR as unknown as SWRHook; @@ -41,59 +41,10 @@ export const PAGINATED_LIST_SIZE = 10; // and use it to know if there are more to request export const PAGINATED_LIST_REQUEST = PAGINATED_LIST_SIZE + 1; -export function revalidateAccountDecisions() { - return mutate( - (key) => Array.isArray(key) && key[key.length - 1] === "getAmlDecisions", - undefined, - { revalidate: true }, - ); -} - /** * @param args * @returns */ -export function useTransferDebit() { - const officer = useOfficer(); - const session = officer.state === "ready" ? officer.session : undefined; - const { - lib: { exchange: api }, - } = useExchangeApiContext(); - - const [pointer, updatePointer] = useListPointer( - (row: ExchangeTransferListEntry) => String(row.rowid), - "debit", - ); - - async function fetcher([officer, offset]: [ - OfficerSession, - ListPointer, - string | undefined, - ]) { - return await api.getTransfersDebit(officer, { - offset: offset?.id, - order: offset?.order, - limit: PAGINATED_LIST_REQUEST, - }); - } - - const { data, error } = useSWR< - TalerExchangeResultByMethod2<"getTransfersDebit">, - TalerHttpError - >(!session ? undefined : [session, pointer, "getTransfersDebit"], fetcher); - - if (error) return error; - if (data === undefined) return undefined; - if (data.type !== "ok") return data; - - return buildPaginatedResult( - data.body.transfers, - pointer, - updatePointer, - PAGINATED_LIST_REQUEST, - ); -} - export type TransferCategory = | "credit" | "debit" diff --git a/packages/taler-exchange-aml-webui/src/pages/AccountList.tsx b/packages/taler-exchange-aml-webui/src/pages/AccountList.tsx @@ -679,26 +679,6 @@ function exportFailureMessage( } } -export const ToInvestigateIcon = ( - props?: h.JSX.SVGAttributes<SVGSVGElement>, -) => ( - <svg - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - stroke-width="1.5" - stroke="currentColor" - class="size-6" - {...props} - > - <path - stroke-linecap="round" - stroke-linejoin="round" - d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" - /> - </svg> -); - export const TransfersIcon = (props?: h.JSX.SVGAttributes<SVGSVGElement>) => ( <svg xmlns="http://www.w3.org/2000/svg" diff --git a/packages/taler-exchange-aml-webui/src/utils/getTimeframesForDate.ts b/packages/taler-exchange-aml-webui/src/utils/getTimeframesForDate.ts @@ -1,87 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022-2025 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 { AbsoluteTime, assertUnreachable } from "@gnu-taler/taler-util"; -import { sub } from "date-fns"; -import { TalerCorebankApi } from "@gnu-taler/taler-util"; - -export type Timeframe = { start: AbsoluteTime; end: AbsoluteTime }; - -export function getTimeframesForDate( - time: Date, - timeframe: TalerCorebankApi.MonitorTimeframeParam, -): { - current: Timeframe; - previous: Timeframe; -} { - switch (timeframe) { - case TalerCorebankApi.MonitorTimeframeParam.hour: { - const [high, middle, low] = [0, 1, 2].map((timeIndex) => - AbsoluteTime.fromMilliseconds( - sub(time, { hours: timeIndex }).getTime(), - ), - ); - return { - current: { start: middle, end: high }, - previous: { start: low, end: middle }, - }; - } - case TalerCorebankApi.MonitorTimeframeParam.day: { - const [high, middle, low] = [0, 1, 2].map((timeIndex) => - AbsoluteTime.fromMilliseconds(sub(time, { days: timeIndex }).getTime()), - ); - return { - current: { start: middle, end: high }, - previous: { start: low, end: middle }, - }; - } - case TalerCorebankApi.MonitorTimeframeParam.month: { - const [high, middle, low] = [0, 1, 2].map((timeIndex) => - AbsoluteTime.fromMilliseconds( - sub(time, { months: timeIndex }).getTime(), - ), - ); - return { - current: { start: middle, end: high }, - previous: { start: low, end: middle }, - }; - } - - case TalerCorebankApi.MonitorTimeframeParam.year: { - const [high, middle, low] = [0, 1, 2].map((timeIndex) => - AbsoluteTime.fromMilliseconds( - sub(time, { years: timeIndex }).getTime(), - ), - ); - return { - current: { start: middle, end: high }, - previous: { start: low, end: middle }, - }; - } - case TalerCorebankApi.MonitorTimeframeParam.decade: { - const [high, middle, low] = [0, 1, 2].map((timeIndex) => - AbsoluteTime.fromMilliseconds( - sub(time, { years: timeIndex * 10 }).getTime(), - ), - ); - return { - current: { start: middle, end: high }, - previous: { start: low, end: middle }, - }; - } - default: - assertUnreachable(timeframe); - } -} diff --git a/packages/taler-exchange-kyc-webui/src/Routing.tsx b/packages/taler-exchange-kyc-webui/src/Routing.tsx @@ -62,15 +62,6 @@ const publicPages = { ), }; -export function safeToURL(s: string | undefined): URL | undefined { - if (s === undefined) return undefined; - try { - return new URL(s); - } catch (e) { - return undefined; - } -} - function PublicRounting(): VNode { const location = useCurrentLocation(publicPages); const { state, start } = useSessionState(); diff --git a/packages/taler-exchange-kyc-webui/src/context/settings.ts b/packages/taler-exchange-kyc-webui/src/context/settings.ts @@ -15,7 +15,6 @@ */ import { ComponentChildren, createContext, h, VNode } from "preact"; -import { useContext } from "preact/hooks"; import { KycUiSettings } from "../settings.js"; /** @@ -28,8 +27,6 @@ export type Type = KycUiSettings; const initial: KycUiSettings = {}; const Context = createContext<Type>(initial); -export const useSettingsContext = (): Type => useContext(Context); - export const SettingsProvider = ({ children, value, diff --git a/packages/taler-exchange-kyc-webui/src/context/ui-forms.ts b/packages/taler-exchange-kyc-webui/src/context/ui-forms.ts @@ -35,8 +35,6 @@ const defaultForms: Type = { const Context = createContext<Type>(defaultForms); -export type BaseForm = Record<string, unknown>; - export const useUiFormsContext = (): Type => useContext(Context); export const UiFormsProvider = ({ diff --git a/packages/taler-exchange-kyc-webui/src/pages/NonceNotFound.tsx b/packages/taler-exchange-kyc-webui/src/pages/NonceNotFound.tsx @@ -1,36 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022-2024 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 { useTranslationContext } from "@gnu-taler/web-util/browser"; -import { Fragment, VNode, h } from "preact"; - -export function NonceNotFound(): VNode { - const { i18n } = useTranslationContext(); - - return ( - <Fragment> - <div class="isolate bg-white px-6 py-12"> - <div class="mx-auto max-w-2xl text-center"> - <h2 class="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl"> - <i18n.Translate>The URL is wrong</i18n.Translate> - </h2> - <p class="mt-2 text-lg leading-8 text-gray-600"> - <i18n.Translate>Maybe the validation check expired.</i18n.Translate> - </p> - </div> - </div> - </Fragment> - ); -} diff --git a/packages/taler-exchange-kyc-webui/src/pages/Start.tsx b/packages/taler-exchange-kyc-webui/src/pages/Start.tsx @@ -445,31 +445,3 @@ function RequirementRow({ } } } - -/** - * Show the element when the load ended - * @param element - */ -export function doAutoFocus(element: HTMLElement | null): void { - if (element) { - setTimeout(() => { - element.focus({ preventScroll: true }); - element.scrollIntoView({ - behavior: "smooth", - block: "center", - inline: "center", - }); - }, 100); - } -} - -export function undefinedIfEmpty<T extends object | undefined>( - obj: T, -): T | undefined { - if (obj === undefined) return undefined; - return Object.keys(obj).some( - (k) => (obj as Record<string, T>)[k] !== undefined, - ) - ? obj - : undefined; -} diff --git a/packages/taler-harness/src/harness/environments.ts b/packages/taler-harness/src/harness/environments.ts @@ -83,14 +83,11 @@ import { HarnessExchangeBankAccount, harnessHttpLib, LibeufinBankService, - MERCHANT_DEFAULT_AUTH, - MERCHANT_DEFAULT_LOGIN_SCOPE, MerchantService, MerchantServiceInterface, PaivanaService, setupDb, useLibeufinBank, - WalletCli, WalletClient, WalletService, WithAuthorization, @@ -125,18 +122,6 @@ export async function loadSelenium() { } /** - * @deprecated - */ -export interface SimpleTestEnvironment { - commonDb: DbInfo; - bank: BankService; - exchange: ExchangeService; - exchangeBankAccount: HarnessExchangeBankAccount; - merchant: MerchantService; - wallet: WalletCli; -} - -/** * Improved version of the simple test environment, * with the daemonized wallet. */ diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts @@ -516,14 +516,6 @@ export function shouldLingerInTest(): boolean { return !!process.env["TALER_TEST_LINGER"]; } -export interface TalerConfigSection { - options: Record<string, string | undefined>; -} - -export interface TalerConfig { - sections: Record<string, TalerConfigSection>; -} - export interface DbInfo { /** * Postgres connection string. @@ -575,11 +567,6 @@ export interface PaivanaConfig { overrideTestDir?: string; } -export interface FakeBankConfig { - currency: string; - httpPort: number; -} - /** * @param name additional component name, needed when launching multiple instances of the same component */ diff --git a/packages/taler-harness/src/harness/sync.ts b/packages/taler-harness/src/harness/sync.ts @@ -1,119 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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/> - */ - -/** - * Imports. - */ -import { URL } from "@gnu-taler/taler-util"; -import * as fs from "node:fs"; -import * as util from "util"; -import { - GlobalTestState, - pingProc, - ProcessWrapper, -} from "../harness/harness.js"; -import { Configuration } from "@gnu-taler/taler-util"; -import * as child_process from "child_process"; - -const exec = util.promisify(child_process.exec); - -export interface SyncConfig { - /** - * Human-readable name used in the test harness logs. - */ - name: string; - - httpPort: number; - - /** - * Database connection string (only postgres is supported). - */ - database: string; - - annualFee: string; - - currency: string; - - uploadLimitMb: number; - - /** - * Fulfillment URL used for contract terms related to - * sync. - */ - fulfillmentUrl: string; - - paymentBackendUrl: string; -} - -function setSyncPaths(config: Configuration, home: string) { - config.setString("paths", "sync_home", home); - // We need to make sure that the path of taler_runtime_dir isn't too long, - // as it contains unix domain sockets (108 character limit). - const runDir = fs.mkdtempSync("/tmp/taler-test-"); - config.setString("paths", "sync_runtime_dir", runDir); - config.setString("paths", "sync_data_home", "$SYNC_HOME/.local/share/sync/"); - config.setString("paths", "sync_config_home", "$SYNC_HOME/.config/sync/"); - config.setString("paths", "sync_cache_home", "$SYNC_HOME/.config/sync/"); -} - -export class SyncService { - static async create( - gc: GlobalTestState, - sc: SyncConfig, - ): Promise<SyncService> { - const config = new Configuration(); - - const cfgFilename = gc.testDir + `/sync-${sc.name}.conf`; - setSyncPaths(config, gc.testDir + "/synchome"); - config.setString("taler", "currency", sc.currency); - config.setString("sync", "serve", "tcp"); - config.setString("sync", "port", `${sc.httpPort}`); - config.setString("sync", "db", "postgres"); - config.setString("syncdb-postgres", "config", sc.database); - config.setString("sync", "payment_backend_url", sc.paymentBackendUrl); - config.setString("sync", "upload_limit_mb", `${sc.uploadLimitMb}`); - config.writeTo(cfgFilename); - - return new SyncService(gc, sc, cfgFilename); - } - - proc: ProcessWrapper | undefined; - - get baseUrl(): string { - return `http://localhost:${this.syncConfig.httpPort}/`; - } - - async start(): Promise<void> { - await exec(`sync-dbinit -c "${this.configFilename}"`); - - this.proc = this.globalState.spawnService( - "sync-httpd", - ["-LDEBUG", "-c", this.configFilename], - `sync-${this.syncConfig.name}`, - ); - } - - async pingUntilAvailable(): Promise<void> { - const url = new URL("config", this.baseUrl).href; - await pingProc(this.proc, url, "sync"); - } - - constructor( - private globalState: GlobalTestState, - private syncConfig: SyncConfig, - private configFilename: string, - ) {} -} diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts @@ -2157,14 +2157,6 @@ playgroundCli }); }); -export const helpersCli = talerHarnessCli.subcommand( - "helperProgram", - "helper-program", - { - help: "Generic helper. Reads stdin and all arguments and send it as a JSON to the socket.", - }, -); - talerHarnessCli .subcommand("helper2faDump", "helper-2fa-dump", { help: "Helper used in integration tests.", diff --git a/packages/taler-harness/src/integrationtests/test-tops-aml-measures.ts b/packages/taler-harness/src/integrationtests/test-tops-aml-measures.ts @@ -17,12 +17,10 @@ /** * Imports. */ -import { j2s, Logger } from "@gnu-taler/taler-util"; +import { j2s } from "@gnu-taler/taler-util"; import { GlobalTestState } from "../harness/harness.js"; import { isFrozen, setupMeasuresTestEnvironment } from "../harness/tops.js"; -export const logger = new Logger("test-tops-aml-measures.ts"); - /** * Test that invokes all measures defined for the TOPS deployment. */ diff --git a/packages/taler-harness/src/integrationtests/test-tops-aml-pdf.ts b/packages/taler-harness/src/integrationtests/test-tops-aml-pdf.ts @@ -17,13 +17,11 @@ /** * Imports. */ -import { Logger, succeedOrThrow } from "@gnu-taler/taler-util"; +import { succeedOrThrow } from "@gnu-taler/taler-util"; import * as fs from "node:fs"; import { GlobalTestState, sh } from "../harness/harness.js"; import { setupMeasuresTestEnvironment } from "../harness/tops.js"; -export const logger = new Logger("test-tops-aml-measures.ts"); - function assertPdf(t: GlobalTestState, data: Uint8Array, label: string): void { const text = Buffer.from(data).toString("latin1"); t.assertTrue(data.byteLength > 100, `${label} is unexpectedly small`); diff --git a/packages/taler-merchant-webui/src/api/contracts.ts b/packages/taler-merchant-webui/src/api/contracts.ts @@ -53,19 +53,6 @@ export type MutationResult<T = void, C = never> = | { type: "challenge"; challenge: C } | { type: "failure"; error: ApiFailure }; -export async function runMutation<T>( - operation: () => Promise<T>, -): Promise<MutationResult<T>> { - try { - return { type: "success", value: await operation() }; - } catch (error) { - return { - type: "failure", - error: normalizeApiFailure(error, { outcome: "indeterminate" }), - }; - } -} - /** Run an MFA continuation that may legitimately start another challenge round. */ export async function runProtectedMutation<T, C>( operation: () => Promise<T | { type: "challenge"; challenge: C }>, diff --git a/packages/taler-merchant-webui/src/api/hooks/useOrders.ts b/packages/taler-merchant-webui/src/api/hooks/useOrders.ts @@ -443,19 +443,6 @@ export function useOrders(params: UseOrdersParams = {}) { }; } -export function useOrderPayUri(): (orderId: string) => Promise<string | undefined> { - const token = session.value.token; - const config = getClientConfig(); - - return async (orderId: string) => { - if (!token) return undefined; - const client = merchantClient(config); - const res = await client.getOrderDetails(token as AccessToken, orderId); - const body = unwrap(res); - return body.order_status === "unpaid" ? body.taler_pay_uri : undefined; - }; -} - export function useOrderDetails(orderId?: string) { const token = session.value.token; const config = getClientConfig(); diff --git a/packages/taler-merchant-webui/src/stores/preferences.ts b/packages/taler-merchant-webui/src/stores/preferences.ts @@ -67,6 +67,3 @@ export function updatePreference<K extends keyof Preferences>( ): void { store.set({ ...store.get(), [key]: value }); } - -/** Test seam. The application never calls this. */ -export const __preferencesStore = store; diff --git a/packages/taler-merchant-webui/src/stores/session.ts b/packages/taler-merchant-webui/src/stores/session.ts @@ -38,8 +38,6 @@ export const lastMerchantAccountStore = persistedSignal<string>( "", ); -export const lastMerchantAccount: Signal<string> = lastMerchantAccountStore.signal; - export const customBackendUrlStore = persistedSignal<string>( "custom_merchant_backend_url", codecForString(), diff --git a/packages/taler-merchant-webui/src/tutorial/demoData.ts b/packages/taler-merchant-webui/src/tutorial/demoData.ts @@ -190,8 +190,6 @@ export function demoSecondPaytoUri(): string { return paytoFor(DEMO_SECOND_ACCOUNT_IBAN, `${DEMO_BUSINESS.account}-2`, DEMO_BUSINESS.name); } -export const DAY_S = 86400; - /** A small, self-contained logo that remains available in offline previews. */ export const DEMO_BUSINESS_LOGO = "data:image/svg+xml;utf8," + diff --git a/packages/taler-merchant-webui/src/tutorial/tutorialData.tsx b/packages/taler-merchant-webui/src/tutorial/tutorialData.tsx @@ -2054,15 +2054,3 @@ export function getTutorialModules(t: TranslateFn): TutorialModule[] { export function getTutorialChapters(t: TranslateFn): TutorialChapter[] { return getTutorialModules(t).flatMap((module) => module.chapters); } - -/** - * How many chapters there are. - * - * Built with an identity translation, because a count does not depend on the - * language and callers that only want the number should not have to hold a - * translation function. - */ -export const TUTORIAL_CHAPTER_COUNT: number = getTutorialChapters( - ((s: TemplateStringsArray | string, ...v: unknown[]) => - typeof s === "string" ? s : s.reduce((acc, part, i) => acc + part + (i < v.length ? String(v[i]) : ""), "")) as TranslateFn, -).length; diff --git a/packages/taler-merchant-webui/src/ui/Badge.tsx b/packages/taler-merchant-webui/src/ui/Badge.tsx @@ -14,31 +14,6 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import type { ComponentChildren } from "preact"; - -export interface BadgeProps { - variant?: "success" | "warning" | "error" | "info" | "neutral" | "brand"; - children: ComponentChildren; - class?: string; -} - -const badgeVariants = { - success: "bg-emerald-100 text-emerald-800 border-emerald-200", - warning: "bg-amber-100 text-amber-800 border-amber-200", - error: "bg-red-100 text-red-800 border-red-200", - info: "bg-blue-100 text-blue-800 border-blue-200", - neutral: "bg-gray-100 text-gray-800 border-gray-200", - brand: "bg-blue-50 text-taler-brand border-blue-200", -}; - -export function Badge({ variant = "neutral", children, class: className = "" }: BadgeProps) { - return ( - <span class={`inline-flex items-center whitespace-nowrap shrink-0 px-2.5 py-0.5 rounded-full text-xs font-semibold border ${badgeVariants[variant]} ${className}`}> - {children} - </span> - ); -} - import { useTranslation } from "../context/translation.js"; /** diff --git a/packages/taler-merchant-webui/src/ui/Card.tsx b/packages/taler-merchant-webui/src/ui/Card.tsx @@ -1,42 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2026 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 type { ComponentChildren } from "preact"; - -export interface CardProps { - title?: string; - subtitle?: string; - action?: ComponentChildren; - children: ComponentChildren; - class?: string; -} - -export function Card({ title, subtitle, action, children, class: className = "" }: CardProps) { - return ( - <div class={`bg-white rounded-xl shadow-2xs border border-gray-200 p-6 space-y-4 ${className}`}> - {(title || action) && ( - <div class="flex items-center justify-between border-b border-gray-100 pb-3"> - <div> - {title && <h2 class="text-base font-bold text-gray-900">{title}</h2>} - {subtitle && <p class="text-xs text-gray-500 mt-0.5">{subtitle}</p>} - </div> - {action && <div>{action}</div>} - </div> - )} - <div>{children}</div> - </div> - ); -} diff --git a/packages/taler-merchant-webui/src/ui/Table.tsx b/packages/taler-merchant-webui/src/ui/Table.tsx @@ -1,29 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2026 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 type { ComponentChildren } from "preact"; - -export interface TableProps { - children: ComponentChildren; - class?: string; -} -export function Table({ children, class: className = "" }: TableProps) { - return ( - <div class={`overflow-x-auto rounded-lg border border-gray-200 ${className}`}> - <table class="min-w-full divide-y divide-gray-200">{children}</table> - </div> - ); -} diff --git a/packages/taler-merchant-webui/src/utils/runtimeValidation.ts b/packages/taler-merchant-webui/src/utils/runtimeValidation.ts @@ -4,13 +4,6 @@ SPDX-License-Identifier: GPL-3.0-or-later */ -export function requireNonEmptyString(value: unknown, field: string): string { - if (typeof value !== "string" || !value.trim()) { - throw new Error(`${field} must be a non-empty string`); - } - return value.trim(); -} - export function parseStrictDate(value: string, field: string): Date { if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) { throw new Error(`${field} must use YYYY-MM-DD`); @@ -21,7 +14,3 @@ export function parseStrictDate(value: string, field: string): Date { } return date; } - -export function isRecord(value: unknown): value is Record<string, unknown> { - return Boolean(value) && typeof value === "object" && !Array.isArray(value); -} diff --git a/packages/taler-util/src/ReserveTransaction.ts b/packages/taler-util/src/ReserveTransaction.ts @@ -1,256 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2019 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/> - */ - -/** - * Type declarations for the exchange's reserve transaction information. - * - * @author Florian Dold <dold@taler.net> - */ - -/** - * Imports. - */ -import { codecForAmountString } from "./amounts.js"; -import { - codecForString, - buildCodecForObject, - codecForConstString, - buildCodecForUnion, - Codec, - codecForNumber, -} from "./codec.js"; -import { - AmountString, - Base32String, - EddsaSignatureString, - EddsaPublicKeyString, - CoinPublicKeyString, - codecForEddsaSignature, - codecForEddsaPublicKey, -} from "./types-taler-common.js"; -import { - AbsoluteTime, - codecForTimestamp, - TalerProtocolTimestamp, -} from "./time.js"; - -export enum ReserveTransactionType { - Withdraw = "WITHDRAW", - Credit = "CREDIT", - Recoup = "RECOUP", - Closing = "CLOSING", -} - -export interface ReserveWithdrawTransaction { - type: ReserveTransactionType.Withdraw; - - /** - * Amount withdrawn. - */ - amount: AmountString; - - /** - * Hash of the denomination public key of the coin. - */ - h_denom_pub: Base32String; - - /** - * Hash of the blinded coin to be signed - */ - h_coin_envelope: Base32String; - - /** - * Signature of 'TALER_WithdrawRequestPS' created with the reserves's - * private key. - */ - reserve_sig: EddsaSignatureString; - - /** - * Fee that is charged for withdraw. - */ - withdraw_fee: AmountString; -} - -export interface ReserveCreditTransaction { - type: ReserveTransactionType.Credit; - - /** - * Amount withdrawn. - */ - amount: AmountString; - - /** - * Sender account payto://-URL - */ - sender_account_url: string; - - /** - * Transfer details uniquely identifying the transfer. - */ - wire_reference: number; - - /** - * Timestamp of the incoming wire transfer. - */ - timestamp: TalerProtocolTimestamp; -} - -export interface ReserveClosingTransaction { - type: ReserveTransactionType.Closing; - - /** - * Closing balance. - */ - amount: AmountString; - - /** - * Closing fee charged by the exchange. - */ - closing_fee: AmountString; - - /** - * Wire transfer subject. - */ - wtid: string; - - /** - * Hash of the wire account into which the funds were returned to. - */ - h_wire: string; - - /** - * This is a signature over a - * struct TALER_ReserveCloseConfirmationPS with purpose - * TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED. - */ - exchange_sig: EddsaSignatureString; - - /** - * Public key used to create exchange_sig. - */ - exchange_pub: EddsaPublicKeyString; - - /** - * Time when the reserve was closed. - */ - timestamp: TalerProtocolTimestamp; -} - -export interface ReserveRecoupTransaction { - type: ReserveTransactionType.Recoup; - - /** - * Amount paid back. - */ - amount: AmountString; - - /** - * This is a signature over - * a struct TALER_PaybackConfirmationPS with purpose - * TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK. - */ - exchange_sig: EddsaSignatureString; - - /** - * Public key used to create exchange_sig. - */ - exchange_pub: EddsaPublicKeyString; - - /** - * Time when the funds were paid back into the reserve. - */ - timestamp: TalerProtocolTimestamp; - - /** - * Public key of the coin that was paid back. - */ - coin_pub: CoinPublicKeyString; -} - -/** - * Format of the exchange's transaction history for a reserve. - */ -export type ReserveTransaction = - | ReserveWithdrawTransaction - | ReserveCreditTransaction - | ReserveClosingTransaction - | ReserveRecoupTransaction; - -export const codecForReserveWithdrawTransaction = - (): Codec<ReserveWithdrawTransaction> => - buildCodecForObject<ReserveWithdrawTransaction>() - .property("amount", codecForAmountString()) - .property("h_coin_envelope", codecForString()) - .property("h_denom_pub", codecForString()) - .property("reserve_sig", codecForEddsaSignature()) - .property("type", codecForConstString(ReserveTransactionType.Withdraw)) - .property("withdraw_fee", codecForAmountString()) - .build("ReserveWithdrawTransaction"); - -export const codecForReserveCreditTransaction = - (): Codec<ReserveCreditTransaction> => - buildCodecForObject<ReserveCreditTransaction>() - .property("amount", codecForAmountString()) - .property("sender_account_url", codecForString()) - .property("timestamp", codecForTimestamp) - .property("wire_reference", codecForNumber()) - .property("type", codecForConstString(ReserveTransactionType.Credit)) - .build("ReserveCreditTransaction"); - -export const codecForReserveClosingTransaction = - (): Codec<ReserveClosingTransaction> => - buildCodecForObject<ReserveClosingTransaction>() - .property("amount", codecForAmountString()) - .property("closing_fee", codecForAmountString()) - .property("exchange_pub", codecForEddsaPublicKey()) - .property("exchange_sig", codecForEddsaSignature()) - .property("h_wire", codecForString()) - .property("timestamp", codecForTimestamp) - .property("type", codecForConstString(ReserveTransactionType.Closing)) - .property("wtid", codecForString()) - .build("ReserveClosingTransaction"); - -export const codecForReserveRecoupTransaction = - (): Codec<ReserveRecoupTransaction> => - buildCodecForObject<ReserveRecoupTransaction>() - .property("amount", codecForAmountString()) - .property("coin_pub", codecForString()) - .property("exchange_pub", codecForEddsaPublicKey()) - .property("exchange_sig", codecForEddsaSignature()) - .property("timestamp", codecForTimestamp) - .property("type", codecForConstString(ReserveTransactionType.Recoup)) - .build("ReserveRecoupTransaction"); - -export const codecForReserveTransaction = (): Codec<ReserveTransaction> => - buildCodecForUnion<ReserveTransaction>() - .discriminateOn("type") - .alternative( - ReserveTransactionType.Withdraw, - codecForReserveWithdrawTransaction(), - ) - .alternative( - ReserveTransactionType.Closing, - codecForReserveClosingTransaction(), - ) - .alternative( - ReserveTransactionType.Recoup, - codecForReserveRecoupTransaction(), - ) - .alternative( - ReserveTransactionType.Credit, - codecForReserveCreditTransaction(), - ) - .build<ReserveTransaction>("ReserveTransaction"); diff --git a/packages/taler-util/src/aml/events.test.ts b/packages/taler-util/src/aml/events.test.ts @@ -1,132 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2026 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 { test } from "node:test"; -import assert from "node:assert"; -import { deriveTopsAmlEvents } from "./events.js"; - -test("AML event derivation for TOPS, unknown form", (t) => { - const events = deriveTopsAmlEvents("some_unknown_form", {}, {}, {}); - assert.deepStrictEqual([...events], []); -}); - -test("AML event derivation for TOPS, vqf_902_1_officer", (t) => { - { - const events = deriveTopsAmlEvents( - "vqf_902_1_officer", - {}, - {}, - { - ACCOUNT_OPEN: true, - }, - ); - assert.deepStrictEqual([...events], ["INCR_ACCOUNT_OPEN"]); - } - - { - // Already open, no event - const events = deriveTopsAmlEvents( - "vqf_902_1_officer", - {}, - { - ACCOUNT_OPEN: true, - }, - { - ACCOUNT_OPEN: true, - }, - ); - assert.deepStrictEqual([...events], []); - } - - { - const events = deriveTopsAmlEvents( - "vqf_902_1_officer", - {}, - {}, - { - ACCOUNT_OPEN: true, - PEP_FOREIGN: true, - }, - ); - assert.deepStrictEqual( - [...events], - ["INCR_ACCOUNT_OPEN", "INCR_PEP", "INCR_PEP_FOREIGN"], - ); - } -}); - -test("AML event derivation for TOPS, vqf_902_4", (t) => { - { - // Account not open => no event - const events = deriveTopsAmlEvents( - "vqf_902_4", - {}, - {}, - { - PEP_FOREIGN: true, - }, - ); - assert.deepStrictEqual([...events], []); - } - { - const events = deriveTopsAmlEvents( - "vqf_902_4", - {}, - { - ACCOUNT_OPEN: true, - }, - { - PEP_FOREIGN: true, - }, - ); - assert.deepStrictEqual([...events], ["INCR_PEP", "INCR_PEP_FOREIGN"]); - } - { - const events = deriveTopsAmlEvents( - "vqf_902_4", - {}, - { - ACCOUNT_OPEN: true, - PEP_FOREIGN: true, - }, - { - PEP_FOREIGN: false, - }, - ); - assert.deepStrictEqual([...events], ["DECR_PEP", "DECR_PEP_FOREIGN"]); - } -}); - -test("AML event derivation for TOPS, first decision on an account", (t) => { - // An account with no previous AML decision has no properties yet. The - // specification's precondition is INVESTIGATION_STATE == null, which covers - // that case, so a report filed on such an account must still be counted. - const events = deriveTopsAmlEvents( - "vqf_902_14_officer", - {}, - undefined as any, - { - INVESTIGATION_STATE: "REPORTED_SUSPICION_SUBSTANTIATED", - }, - ); - assert.deepStrictEqual( - [...events].sort(), - [ - "INCR_INVESTIGATION_CONCLUDED", - "MROS_REPORTED_SUSPICION_SUBSTANTIATED", - ].sort(), - ); -}); diff --git a/packages/taler-util/src/aml/events.ts b/packages/taler-util/src/aml/events.ts @@ -1,15 +1,8 @@ -import { Amounts } from "../amounts.js"; import { TalerAmlProperties } from "../taler-account-properties.js"; import { AccountProperties, - KycRule, - LimitOperationType, } from "../types-taler-exchange.js"; -import { - AmlFormAttributesMap, - isOneOf, - TopsAccountPropertiesMap, -} from "./properties.js"; +import { isOneOf } from "./properties.js"; // FIXME: We really ought to have a GANA registry for AML event names @@ -77,19 +70,6 @@ export type EventMapInfo<T> = { }; }; -function isAllowToMakeDeposits(limits: KycRule[]) { - const depositLimits = limits.filter( - (r) => r.operation_type === LimitOperationType.deposit, - ); - // no deposit limits - if (!depositLimits.length) return true; - const zero = depositLimits.find((d) => Amounts.isZero(d.threshold)); - // there is a rule that prohibit deposit - if (zero) return false; - // the cusomter can at least make some deposits - return true; -} - function propBecameTrue( prevState: AccountProperties | undefined, nextState: AccountProperties, @@ -549,23 +529,3 @@ export const EventsDerivation_TOPS: EventMapInfo<typeof TOPS_AmlEventsName> = { }, }, }; - -const topsEventNames = Object.values(TOPS_AmlEventsName); - -export function deriveTopsAmlEvents( - formId: string, - newAttributes: AmlFormAttributesMap, - oldProperties: TopsAccountPropertiesMap, - newProperties: TopsAccountPropertiesMap, -): Set<TOPS_AmlEventsName> { - const events: Set<TOPS_AmlEventsName> = new Set(); - for (const evt of topsEventNames) { - const h = EventsDerivation_TOPS[evt]; - if ( - h.shouldBeTriggered(formId, oldProperties, newProperties, newAttributes) - ) { - events.add(evt); - } - } - return events; -} diff --git a/packages/taler-util/src/aml/reporting.ts b/packages/taler-util/src/aml/reporting.ts @@ -339,10 +339,6 @@ export interface PartialStatisticsResult<T> { failures: StatisticsQueryFailure[]; } -export type EventQueryByEventName<T> = { - [name in keyof T]: EventQuery<string>; -}; - function safeSub( a: number | undefined, b: number | undefined, diff --git a/packages/taler-util/src/bank-api-client.ts b/packages/taler-util/src/bank-api-client.ts @@ -85,11 +85,6 @@ export interface BankAccessApiClientArgs { httpClient?: HttpRequestLibrary; } -export interface AccountBalance { - amount: AmountString; - credit_debit_indicator: "credit" | "debit"; -} - export interface ConfirmWithdrawalArgs { withdrawalOperationId: string; } @@ -159,7 +154,10 @@ export class TalerCorebankApiClient { } async getTransactions(username: string): Promise<void> { - const reqUrl = new URL(`accounts/${pathSegment(username)}/transactions`, this.baseUrl); + const reqUrl = new URL( + `accounts/${pathSegment(username)}/transactions`, + this.baseUrl, + ); const resp = await this.httpLib.fetch(reqUrl.href, { method: "GET", headers: { @@ -259,7 +257,10 @@ export class TalerCorebankApiClient { user: string, amount: string | undefined, ): Promise<WithdrawalOperationInfo> { - const url = new URL(`accounts/${pathSegment(user)}/withdrawals`, this.baseUrl); + const url = new URL( + `accounts/${pathSegment(user)}/withdrawals`, + this.baseUrl, + ); const resp = await this.httpLib.fetch(url.href, { method: "POST", body: { diff --git a/packages/taler-util/src/bitcoin.ts b/packages/taler-util/src/bitcoin.ts @@ -22,7 +22,6 @@ /** * Imports. */ -import { AmountJson, Amounts } from "./amounts.js"; import { BtAddrString } from "./payto.js"; import { Result } from "./result.js"; import { BitcoinSewgit } from "./segwit_addr.js"; @@ -87,6 +86,3 @@ export function generateFakeSegwitAddress( } // https://github.com/bitcoin/bitcoin/blob/master/src/policy/policy.cpp -export function segwitMinAmount(currency: string): AmountJson { - return Amounts.parseOrThrow(`${currency}:0.00000294`); -} diff --git a/packages/taler-util/src/codec.ts b/packages/taler-util/src/codec.ts @@ -667,40 +667,6 @@ export function codecForStringURL(shouldEndWithSlash?: boolean): Codec<string> { } /** - * Return a codec for a value that must be a string. - */ -export function codecForURL(shouldEndWithSlash?: boolean): Codec<URL> { - return { - decode(x: any, c?: Context): URL { - if (typeof x !== "string") { - throw new DecodingError( - `expected string at ${renderContext(c)} but got ${typeof x}`, - ); - } - if (shouldEndWithSlash && !x.endsWith("/")) { - throw new DecodingError( - `expected URL string that ends with slash at ${renderContext( - c, - )} but got ${x}`, - ); - } - try { - const url = new URL(x); - return url; - } catch (e) { - if (e instanceof Error) { - throw new DecodingError(e.message); - } else { - throw new DecodingError( - `expected an URL string at ${renderContext(c)} but got "${x}"`, - ); - } - } - }, - }; -} - -/** * Codec that allows any value. */ export function codecForAny(): Codec<any> { @@ -737,38 +703,6 @@ export function codecForConstString<V extends string>(s: V): Codec<V> { } /** - * Return a codec for a boolean true constant. - */ -export function codecForConstTrue(): Codec<true> { - return { - decode(x: any, c?: Context): true { - if (x === true) { - return x; - } - throw new DecodingError( - `expected boolean true at ${renderContext(c)} but got ${typeof x}`, - ); - }, - }; -} - -/** - * Return a codec for a boolean true constant. - */ -export function codecForConstFalse(): Codec<false> { - return { - decode(x: any, c?: Context): false { - if (x === false) { - return x; - } - throw new DecodingError( - `expected boolean false at ${renderContext(c)} but got ${typeof x}`, - ); - }, - }; -} - -/** * Return a codec for a value that must be a constant number. */ export function codecForConstNumber<V extends number>(n: V): Codec<V> { @@ -811,18 +745,6 @@ export function codecOptionalDefault<V>( }; } -export function codecForLazy<V>(innerCodec: () => Codec<V>): Codec<V> { - let instance: Codec<V> | undefined = undefined; - return { - decode(x: any, c?: Context): V { - if (instance === undefined) { - instance = innerCodec(); - } - return instance.decode(x, c); - }, - }; -} - export type CodecType<T> = T extends Codec<infer X> ? X : any; // Codec<any>, not Codec<unknown>: Codec is invariant, and only `any` stays diff --git a/packages/taler-util/src/errors.ts b/packages/taler-util/src/errors.ts @@ -17,10 +17,7 @@ import { CancellationToken } from "./CancellationToken.js"; import { TalerErrorCode } from "./taler-error-codes.js"; import { AbsoluteTime } from "./time.js"; -import { - TransactionState, - TransactionType, -} from "./types-taler-wallet-transactions.js"; +import { TransactionState } from "./types-taler-wallet-transactions.js"; import { PaymentInsufficientBalanceDetails, TalerErrorDetail, @@ -330,9 +327,6 @@ export interface DetailsMap { type ErrBody<Y> = Y extends keyof DetailsMap ? DetailsMap[Y] : empty; -export type TypedTalerErrorDetail<Y> = TalerErrorDetail & - (Y extends keyof DetailsMap ? DetailsMap[Y] : {}); - export function makeErrorDetail<C extends TalerErrorCode>( code: C, detail: ErrBody<C>, @@ -345,17 +339,6 @@ export function makeErrorDetail<C extends TalerErrorCode>( return { code, when, hint, ...detail }; } -export function makePendingOperationFailedError( - innerError: TalerErrorDetail, - tag: TransactionType, - uid: string, -): TalerError { - return TalerError.fromDetail(TalerErrorCode.WALLET_PENDING_OPERATION_FAILED, { - innerError, - transactionId: `${tag}:${uid}`, - }); -} - export function summarizeTalerErrorDetail(ed: TalerErrorDetail): string { const errName = TalerErrorCode[ed.code] ?? "<unknown>"; return `Error (${ed.code}/${errName})`; diff --git a/packages/taler-util/src/helpers.ts b/packages/taler-util/src/helpers.ts @@ -99,20 +99,6 @@ export function j2s(x: any): string { } /** - * Use this to filter null or undefined from an array in a type-safe fashion - * - * example: - * const array: Array<T | undefined> = [undefined, null] - * const filtered: Array<T> = array.filter(notEmpty) - * - * @param value - * @returns - */ -export function notEmpty<T>(value: T | null | undefined): value is T { - return value !== null && value !== undefined; -} - -/** * Safe function to stringify errors. */ export function stringifyError(x: any): string { diff --git a/packages/taler-util/src/http-client/bank-integration.ts b/packages/taler-util/src/http-client/bank-integration.ts @@ -21,10 +21,8 @@ import { createPlatformHttpLib } from "../http.js"; import { LibtoolVersion } from "../libtool-version.js"; import { Logger } from "../logging.js"; import { - FailCasesByMethod, OperationFail, OperationOk, - ResultByMethod, carefullyParseConfig, opEmptySuccess, opKnownHttpFailure, @@ -44,16 +42,7 @@ import { } from "../types-taler-bank-integration.js"; import { codecForIntegrationBankConfig } from "../types-taler-corebank.js"; import { codecForTalerErrorDetail } from "../types-taler-wallet.js"; -import { addLongPollingParam, - pathSegment, -} from "./utils.js"; - -export type TalerBankIntegrationResultByMethod< - prop extends keyof TalerBankIntegrationHttpClient, -> = ResultByMethod<TalerBankIntegrationHttpClient, prop>; -export type TalerBankIntegrationErrorsByMethod< - prop extends keyof TalerBankIntegrationHttpClient, -> = FailCasesByMethod<TalerBankIntegrationHttpClient, prop>; +import { addLongPollingParam, pathSegment } from "./utils.js"; const logger = new Logger("bank-integration.ts"); @@ -124,7 +113,10 @@ export class TalerBankIntegrationHttpClient { | OperationFail<HttpStatusCode.NotFound> | OperationFail<HttpStatusCode.Conflict> > { - const url = new URL(`withdrawal-operation/${pathSegment(woid)}`, this.baseUrl); + const url = new URL( + `withdrawal-operation/${pathSegment(woid)}`, + this.baseUrl, + ); addLongPollingParam(url, params); if (params) { // old_state is the long-poll trigger: the server returns as soon as @@ -168,7 +160,10 @@ export class TalerBankIntegrationHttpClient { | OperationFail<TalerErrorCode.BANK_AMOUNT_DIFFERS> | OperationFail<TalerErrorCode.BANK_UNALLOWED_DEBIT> > { - const url = new URL(`withdrawal-operation/${pathSegment(woid)}`, this.baseUrl); + const url = new URL( + `withdrawal-operation/${pathSegment(woid)}`, + this.baseUrl, + ); const resp = await this.httpLib.fetch(url.href, { method: "POST", cancellationToken: this.cancellationToken, @@ -221,7 +216,10 @@ export class TalerBankIntegrationHttpClient { | OperationOk<undefined> | OperationFail<HttpStatusCode.Conflict> > { - const url = new URL(`withdrawal-operation/${pathSegment(woid)}/abort`, this.baseUrl); + const url = new URL( + `withdrawal-operation/${pathSegment(woid)}/abort`, + this.baseUrl, + ); const resp = await this.httpLib.fetch(url.href, { method: "POST", cancellationToken: this.cancellationToken, diff --git a/packages/taler-util/src/http-client/bank-prepared.ts b/packages/taler-util/src/http-client/bank-prepared.ts @@ -27,24 +27,15 @@ import { import { TalerErrorCode } from "../taler-error-codes.js"; import { codecForTalerErrorDetail } from "../types-taler-wallet.js"; import { - FailCasesByMethod, opKnownHttpFailure, opSuccessFromHttp, opUnknownHttpFailure, - ResultByMethod, } from "../operation.js"; import { codecForPreparedTransferConfig, codecForRegistrationResponse, } from "../types-taler-prepared-transfer.js"; -export type TalerPreparedTransferResultByMethod< - prop extends keyof TalerPreparedTransferHttpClient, -> = ResultByMethod<TalerPreparedTransferHttpClient, prop>; -export type TalerPreparedTransferErrorsByMethod< - prop extends keyof TalerPreparedTransferHttpClient, -> = FailCasesByMethod<TalerPreparedTransferHttpClient, prop>; - /** * Allows Taler clients to prepared wire transfers, enabling recurring * wire transfers and optimized transfer flow. diff --git a/packages/taler-util/src/http-client/bank-revenue.ts b/packages/taler-util/src/http-client/bank-revenue.ts @@ -20,12 +20,10 @@ import { createPlatformHttpLib } from "../http.js"; import { LibtoolVersion } from "../libtool-version.js"; import { carefullyParseConfig, - FailCasesByMethod, opFixedSuccess, opKnownHttpFailure, opSuccessFromHttp, opUnknownHttpFailure, - ResultByMethod, } from "../operation.js"; import { LongPollParams, PaginationParams } from "../types-taler-common.js"; import { @@ -39,13 +37,6 @@ import { BasicOrTokenAuth, } from "./utils.js"; -export type TalerBankRevenueResultByMethod< - prop extends keyof TalerRevenueHttpClient, -> = ResultByMethod<TalerRevenueHttpClient, prop>; -export type TalerBankRevenueErrorsByMethod< - prop extends keyof TalerRevenueHttpClient, -> = FailCasesByMethod<TalerRevenueHttpClient, prop>; - /** * The API is used by the merchant (or other parties) to query * for incoming transactions to their account. diff --git a/packages/taler-util/src/http-client/bank-wire.ts b/packages/taler-util/src/http-client/bank-wire.ts @@ -18,12 +18,10 @@ import { HttpRequestLibrary, readTalerErrorResponse } from "../http-common.js"; import { HttpStatusCode } from "../http-status-codes.js"; import { createPlatformHttpLib } from "../http.js"; import { - FailCasesByMethod, opFixedSuccess, opKnownHttpFailure, opSuccessFromHttp, opUnknownHttpFailure, - ResultByMethod, } from "../operation.js"; import { codecForAddIncomingResponse, @@ -48,13 +46,6 @@ import { codecForTalerErrorDetail } from "../types-taler-wallet.js"; import { LongPollParams, PaginationParams } from "../types-taler-common.js"; import * as TalerWireGatewayApi from "../types-taler-wire-gateway.js"; -export type TalerWireGatewayResultByMethod< - prop extends keyof TalerWireGatewayHttpClient, -> = ResultByMethod<TalerWireGatewayHttpClient, prop>; -export type TalerWireGatewayErrorsByMethod< - prop extends keyof TalerWireGatewayHttpClient, -> = FailCasesByMethod<TalerWireGatewayHttpClient, prop>; - /** * The API is used by the exchange to trigger transactions and query * incoming transactions, as well as by the auditor to query incoming @@ -184,7 +175,10 @@ export class TalerWireGatewayHttpClient { * */ async getTransferStatus(req: { rowId?: number; auth?: BasicOrTokenAuth }) { - const url = new URL(`transfers/${pathSegment(String(req.rowId))}`, this.baseUrl); + const url = new URL( + `transfers/${pathSegment(String(req.rowId))}`, + this.baseUrl, + ); const resp = await this.httpLib.fetch(url.href, { method: "GET", headers: authHeaders(req.auth), diff --git a/packages/taler-util/src/http-client/challenger.ts b/packages/taler-util/src/http-client/challenger.ts @@ -24,14 +24,12 @@ import { HttpStatusCode } from "../http-status-codes.js"; import { createPlatformHttpLib } from "../http.js"; import { LibtoolVersion } from "../libtool-version.js"; import { - FailCasesByMethod, ResultByMethod, carefullyParseConfig, opFixedSuccess, opKnownAlternativeHttpFailure, opKnownHttpFailure, opSuccessFromHttp, - opUnknownFailure, opUnknownHttpFailure, } from "../operation.js"; import { @@ -55,8 +53,6 @@ import { export type ChallengerResultByMethod<prop extends keyof ChallengerHttpClient> = ResultByMethod<ChallengerHttpClient, prop>; -export type ChallengerErrorsByMethod<prop extends keyof ChallengerHttpClient> = - FailCasesByMethod<ChallengerHttpClient, prop>; export enum ChallengerCacheEviction { CREATE_CHALLENGE, diff --git a/packages/taler-util/src/http-client/exchange-client.ts b/packages/taler-util/src/http-client/exchange-client.ts @@ -26,7 +26,6 @@ import { HttpStatusCode } from "../http-status-codes.js"; import { createPlatformHttpLib } from "../http.js"; import { LibtoolVersion } from "../libtool-version.js"; import { - FailCasesByMethod, OperationAlternative, OperationFail, OperationOk, @@ -163,9 +162,6 @@ import { EmptyObject } from "../types-taler-wallet.js"; export type TalerExchangeResultByMethod2< prop extends keyof TalerExchangeHttpClient, > = ResultByMethod<TalerExchangeHttpClient, prop>; -export type TalerExchangeErrorsByMethod2< - prop extends keyof TalerExchangeHttpClient, -> = FailCasesByMethod<TalerExchangeHttpClient, prop>; const logger = new Logger("exchange-client.ts"); diff --git a/packages/taler-util/src/http-client/mailbox.ts b/packages/taler-util/src/http-client/mailbox.ts @@ -17,7 +17,6 @@ import { CancellationToken, EddsaSignatureString, - FailCasesByMethod, HttpStatusCode, LibtoolVersion, MailboxConfiguration, @@ -27,7 +26,6 @@ import { OperationAlternative, OperationFail, OperationOk, - ResultByMethod, TalerMailboxApi, carefullyParseConfig, codecForEmptyObject, @@ -50,13 +48,6 @@ import { } from "@gnu-taler/taler-util/http"; import { pathSegment } from "./utils.js"; -export type TalerMailboxInstanceResultByMethod< - prop extends keyof TalerMailboxInstanceHttpClient, -> = ResultByMethod<TalerMailboxInstanceHttpClient, prop>; -export type TalerMailboxInstanceErrorsByMethod< - prop extends keyof TalerMailboxInstanceHttpClient, -> = FailCasesByMethod<TalerMailboxInstanceHttpClient, prop>; - export interface MailboxMessagesResponseRaw { messages: Uint8Array; etag: string; @@ -266,7 +257,10 @@ export class TalerMailboxInstanceHttpClient { | OperationFail<HttpStatusCode.NotFound> | OperationFail<HttpStatusCode.TooManyRequests> > { - const url = new URL(`info/${pathSegment(hMailbox.toUpperCase())}`, this.baseUrl); + const url = new URL( + `info/${pathSegment(hMailbox.toUpperCase())}`, + this.baseUrl, + ); const resp = await this.httpLib.fetch(url.href, { method: "GET", diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts @@ -21,7 +21,6 @@ import { ChallengeRequestResponse, ChallengeSolveRequest, Duration, - FailCasesByMethod, HttpStatusCode, LibtoolVersion, LoginTokenRequest, @@ -30,7 +29,6 @@ import { OperationFail, OperationOk, PaginationParams, - ResultByMethod, TalerErrorCode, TalerMerchantApi, TokenFamilyDetails, @@ -118,13 +116,6 @@ import { pathSegment, } from "./utils.js"; -export type TalerMerchantInstanceResultByMethod< - prop extends keyof TalerMerchantInstanceHttpClient, -> = ResultByMethod<TalerMerchantInstanceHttpClient, prop>; -export type TalerMerchantInstanceErrorsByMethod< - prop extends keyof TalerMerchantInstanceHttpClient, -> = FailCasesByMethod<TalerMerchantInstanceHttpClient, prop>; - /** * FIXME: This should probably not be part of the core merchant HTTP client. */ @@ -177,11 +168,6 @@ export enum TalerMerchantManagementCacheEviction { DELETE_INSTANCE, } -export interface MerchantKycStatusResult { - kyc_data: TalerMerchantApi.MerchantAccountKycRedirect[]; - etag?: string; -} - /** * Protocol version spoken with the core bank. * @@ -3933,13 +3919,6 @@ export class TalerMerchantInstanceHttpClient { } } -export type TalerMerchantManagementResultByMethod< - prop extends keyof TalerMerchantManagementHttpClient, -> = ResultByMethod<TalerMerchantManagementHttpClient, prop>; -export type TalerMerchantManagementErrorsByMethod< - prop extends keyof TalerMerchantManagementHttpClient, -> = FailCasesByMethod<TalerMerchantManagementHttpClient, prop>; - export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttpClient { readonly cacheManagementEvictor: CacheEvictor< TalerMerchantInstanceCacheEviction | TalerMerchantManagementCacheEviction diff --git a/packages/taler-util/src/http-client/taldir.ts b/packages/taler-util/src/http-client/taldir.ts @@ -17,24 +17,19 @@ import { CancellationToken, EmptyObject, - FailCasesByMethod, HttpStatusCode, LibtoolVersion, OperationAlternative, OperationFail, OperationOk, - PaymentResponse, RelativeTime, - ResultByMethod, TaldirAlreadyPaidResponse, TaldirMailboxDetailResponse, - TaldirRateLimitedResponse, TalerDirectoryApi, TalerErrorDetail, carefullyParseConfig, codecForAny, codecForTaldirAlreadyPaidResponse, - codecForTaldirMailboxDetailResponse, codecForTalerDirectoryConfigResponse, opFixedSuccess, opKnownHttpFailure, @@ -47,13 +42,6 @@ import { } from "@gnu-taler/taler-util/http"; import { pathSegment } from "./utils.js"; -export type TalerDirectoryInstanceResultByMethod< - prop extends keyof TalerDirectoryInstanceHttpClient, -> = ResultByMethod<TalerDirectoryInstanceHttpClient, prop>; -export type TalerDirectoryInstanceErrorsByMethod< - prop extends keyof TalerDirectoryInstanceHttpClient, -> = FailCasesByMethod<TalerDirectoryInstanceHttpClient, prop>; - /** * Protocol version spoken with the service. * @@ -134,10 +122,7 @@ export class TalerDirectoryInstanceHttpClient { return opSuccessFromHttp(resp, codecForAny()); } case HttpStatusCode.NotFound: { - return opKnownHttpFailure( - resp.status, - resp, - ); + return opKnownHttpFailure(resp.status, resp); } default: return opUnknownHttpFailure(resp); @@ -172,24 +157,15 @@ export class TalerDirectoryInstanceHttpClient { return opFixedSuccess(resp, resp.status); } case HttpStatusCode.NotFound: { - return opKnownHttpFailure( - resp.status, - resp, - ); + return opKnownHttpFailure(resp.status, resp); } case HttpStatusCode.Forbidden: { - return opKnownHttpFailure( - resp.status, - resp, - ); + return opKnownHttpFailure(resp.status, resp); } case HttpStatusCode.TooManyRequests: { - return opKnownHttpFailure( - resp.status, - resp, - ); + return opKnownHttpFailure(resp.status, resp); } - default: + default: return opUnknownHttpFailure(resp); } } @@ -238,21 +214,13 @@ export class TalerDirectoryInstanceHttpClient { return opKnownHttpFailure(resp.status, resp); } case HttpStatusCode.NotFound: { - return opKnownHttpFailure( - resp.status, - resp, - ); + return opKnownHttpFailure(resp.status, resp); } case HttpStatusCode.TooManyRequests: { - return opKnownHttpFailure( - resp.status, - resp, - ); + return opKnownHttpFailure(resp.status, resp); } default: - return opUnknownHttpFailure(resp); + return opUnknownHttpFailure(resp); } } - - } diff --git a/packages/taler-util/src/http-common.ts b/packages/taler-util/src/http-common.ts @@ -454,100 +454,6 @@ export async function expectSuccessResponseOrThrow<T>( throwUnexpectedRequestError(httpResponse, errResp); } -export async function readSuccessResponseTextOrErrorCode<T>( - httpResponse: HttpResponse, -): Promise<ResponseOrError<string>> { - if (!(httpResponse.status >= 200 && httpResponse.status < 300)) { - let errJson; - try { - errJson = await httpResponse.json(); - } catch (e) { - throw TalerError.fromDetail( - TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, - { - requestUrl: httpResponse.requestUrl, - requestMethod: httpResponse.requestMethod, - httpStatusCode: httpResponse.status, - response: await httpResponse.text(), - validationError: e instanceof Error ? e.message : String(e), - }, - "Couldn't parse JSON format from error response", - ); - } - - const talerErrorCode = errJson?.code; - if (typeof talerErrorCode !== "number") { - throw TalerError.fromDetail( - TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, - { - httpStatusCode: httpResponse.status, - requestUrl: httpResponse.requestUrl, - response: await httpResponse.text(), - requestMethod: httpResponse.requestMethod, - }, - "Error response did not contain error code", - ); - } - return { - isError: true, - talerErrorResponse: errJson, - }; - } - const respJson = await httpResponse.text(); - return { - isError: false, - response: respJson, - }; -} - -export async function checkSuccessResponseOrThrow( - httpResponse: HttpResponse, -): Promise<void> { - if (!(httpResponse.status >= 200 && httpResponse.status < 300)) { - let errJson; - try { - errJson = await httpResponse.json(); - } catch (e) { - throw TalerError.fromDetail( - TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, - { - requestUrl: httpResponse.requestUrl, - requestMethod: httpResponse.requestMethod, - httpStatusCode: httpResponse.status, - response: await httpResponse.text(), - validationError: e instanceof Error ? e.message : String(e), - }, - "Couldn't parse JSON format from error response", - ); - } - - const talerErrorCode = errJson?.code; - if (typeof talerErrorCode !== "number") { - throw TalerError.fromDetail( - TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, - { - httpStatusCode: httpResponse.status, - requestUrl: httpResponse.requestUrl, - response: await httpResponse.text(), - requestMethod: httpResponse.requestMethod, - }, - "Error response did not contain error code", - ); - } - throwUnexpectedRequestError(httpResponse, errJson); - } -} - -export async function readSuccessResponseTextOrThrow<T>( - httpResponse: HttpResponse, -): Promise<string> { - const r = await readSuccessResponseTextOrErrorCode(httpResponse); - if (!r.isError) { - return r.response; - } - throwUnexpectedRequestError(httpResponse, r.talerErrorResponse); -} - export interface HttpLibArgs { enableThrottling?: boolean; /** diff --git a/packages/taler-util/src/i18n.ts b/packages/taler-util/src/i18n.ts @@ -33,7 +33,6 @@ export function internalSetStrings(langStrings: any): void { declare const __translated: unique symbol; export type TranslatedString = string & { [__translated]: true }; -export type ToTranslateString = string & { [__translated]: true }; /** * Convert template strings to a msgid @@ -115,24 +114,6 @@ export function Translate({ return replacePlaceholderWithValues(translation, c); } -/** - * Get an internationalized string (based on the globally set, current language) - * from a JSON object. Fall back to the default language of the JSON object - * if no match exists. - */ -export function getJsonI18n<K extends string>( - obj: Record<K, string>, - key: K, -): string { - return obj[key]; -} - -export function getTranslatedArray(array: Array<any>) { - const s = stringifyArray(array); - const translation: TranslatedString = jed.ngettext(s, s, 1); - return replacePlaceholderWithValues(translation, array); -} - function replacePlaceholderWithValues( translation: TranslatedString, childArray: Array<any>, diff --git a/packages/taler-util/src/iban.ts b/packages/taler-util/src/iban.ts @@ -67,12 +67,6 @@ export type IbanValidationResult = normalizedIban: string; }; -export interface IbanCountryInfo { - name: string; - isSepa?: boolean; - length?: number; -} - const ccZero = "0".charCodeAt(0); const ccNine = "9".charCodeAt(0); const ccA = "A".charCodeAt(0); @@ -374,150 +368,3 @@ export const ibanCountryLengths: Readonly<Record<string, number>> = { XK: 20, YE: 30, }; - -/** - * Incomplete list, see https://www.swift.com/resource/iban-registry-pdf - */ -export const ibanCountryInfoTable: Record<string, IbanCountryInfo> = { - AE: { name: "U.A.E." }, - AF: { name: "Afghanistan" }, - AL: { name: "Albania" }, - AM: { name: "Armenia" }, - AN: { name: "Netherlands Antilles" }, - AR: { name: "Argentina" }, - AT: { name: "Austria" }, - AU: { name: "Australia" }, - AZ: { name: "Azerbaijan" }, - BA: { name: "Bosnia and Herzegovina" }, - BD: { name: "Bangladesh" }, - BE: { name: "Belgium" }, - BG: { name: "Bulgaria" }, - BH: { name: "Bahrain" }, - BN: { name: "Brunei Darussalam" }, - BO: { name: "Bolivia" }, - BR: { name: "Brazil" }, - BT: { name: "Bhutan" }, - BY: { name: "Belarus" }, - BZ: { name: "Belize" }, - CA: { name: "Canada" }, - CG: { name: "Congo" }, - CH: { name: "Switzerland" }, - CI: { name: "Cote d'Ivoire" }, - CL: { name: "Chile" }, - CM: { name: "Cameroon" }, - CN: { name: "People's Republic of China" }, - CO: { name: "Colombia" }, - CR: { name: "Costa Rica" }, - CS: { name: "Serbia and Montenegro" }, - CZ: { name: "Czech Republic" }, - DE: { name: "Germany" }, - DK: { name: "Denmark" }, - DO: { name: "Dominican Republic" }, - DZ: { name: "Algeria" }, - EC: { name: "Ecuador" }, - EE: { name: "Estonia" }, - EG: { name: "Egypt" }, - ER: { name: "Eritrea" }, - ES: { name: "Spain" }, - ET: { name: "Ethiopia" }, - FI: { name: "Finland" }, - FO: { name: "Faroe Islands" }, - FR: { name: "France" }, - GB: { name: "United Kingdom" }, - GD: { name: "Caribbean" }, - GE: { name: "Georgia" }, - GL: { name: "Greenland" }, - GR: { name: "Greece" }, - GT: { name: "Guatemala" }, - HK: { name: "Hong Kong S.A.R." }, - HN: { name: "Honduras" }, - HR: { name: "Croatia" }, - HT: { name: "Haiti" }, - HU: { name: "Hungary" }, - ID: { name: "Indonesia" }, - IE: { name: "Ireland" }, - IL: { name: "Israel" }, - IN: { name: "India" }, - IQ: { name: "Iraq" }, - IR: { name: "Iran" }, - IS: { name: "Iceland" }, - IT: { name: "Italy" }, - JM: { name: "Jamaica" }, - JO: { name: "Jordan" }, - JP: { name: "Japan" }, - KE: { name: "Kenya" }, - KG: { name: "Kyrgyzstan" }, - KH: { name: "Cambodia" }, - KR: { name: "South Korea" }, - KW: { name: "Kuwait" }, - KZ: { name: "Kazakhstan" }, - LA: { name: "Laos" }, - LB: { name: "Lebanon" }, - LI: { name: "Liechtenstein" }, - LK: { name: "Sri Lanka" }, - LT: { name: "Lithuania" }, - LU: { name: "Luxembourg" }, - LV: { name: "Latvia" }, - LY: { name: "Libya" }, - MA: { name: "Morocco" }, - MC: { name: "Principality of Monaco" }, - MD: { name: "Moldava" }, - ME: { name: "Montenegro" }, - MK: { name: "Former Yugoslav Republic of Macedonia" }, - ML: { name: "Mali" }, - MM: { name: "Myanmar" }, - MN: { name: "Mongolia" }, - MO: { name: "Macau S.A.R." }, - MT: { name: "Malta" }, - MV: { name: "Maldives" }, - MX: { name: "Mexico" }, - MY: { name: "Malaysia" }, - NG: { name: "Nigeria" }, - NI: { name: "Nicaragua" }, - NL: { name: "Netherlands" }, - NO: { name: "Norway" }, - NP: { name: "Nepal" }, - NZ: { name: "New Zealand" }, - OM: { name: "Oman" }, - PA: { name: "Panama" }, - PE: { name: "Peru" }, - PH: { name: "Philippines" }, - PK: { name: "Islamic Republic of Pakistan" }, - PL: { name: "Poland" }, - PR: { name: "Puerto Rico" }, - PT: { name: "Portugal" }, - PY: { name: "Paraguay" }, - QA: { name: "Qatar" }, - RE: { name: "Reunion" }, - RO: { name: "Romania" }, - RS: { name: "Serbia" }, - RU: { name: "Russia" }, - RW: { name: "Rwanda" }, - SA: { name: "Saudi Arabia" }, - SE: { name: "Sweden" }, - SG: { name: "Singapore" }, - SI: { name: "Slovenia" }, - SK: { name: "Slovak" }, - SN: { name: "Senegal" }, - SO: { name: "Somalia" }, - SR: { name: "Suriname" }, - SV: { name: "El Salvador" }, - SY: { name: "Syria" }, - TH: { name: "Thailand" }, - TJ: { name: "Tajikistan" }, - TM: { name: "Turkmenistan" }, - TN: { name: "Tunisia" }, - TR: { name: "Turkey" }, - TT: { name: "Trinidad and Tobago" }, - TW: { name: "Taiwan" }, - TZ: { name: "Tanzania" }, - UA: { name: "Ukraine" }, - US: { name: "United States" }, - UY: { name: "Uruguay" }, - VA: { name: "Vatican" }, - VE: { name: "Venezuela" }, - VN: { name: "Viet Nam" }, - YE: { name: "Yemen" }, - ZA: { name: "South Africa" }, - ZW: { name: "Zimbabwe" }, -}; diff --git a/packages/taler-util/src/index.node.ts b/packages/taler-util/src/index.node.ts @@ -21,5 +21,4 @@ initNodePrng(); export * from "./index.js"; export * from "./talerconfig.js"; export * from "./globbing/minimatch.js"; -export * from "./kyc-aml-utils.js"; export { setPrintHttpRequestAsCurl } from "./http-impl.node.js"; diff --git a/packages/taler-util/src/index.ts b/packages/taler-util/src/index.ts @@ -58,7 +58,6 @@ export * from "./promises.js"; export * from "./qr.js"; export { RequestThrottler } from "./RequestThrottler.js"; export * from "./ReserveStatus.js"; -export * from "./ReserveTransaction.js"; export * from "./rfc3548.js"; export * from "./taler-crypto.js"; export * from "./taler_signatures.js"; @@ -81,7 +80,6 @@ export * from "./types-taler-merchant.js"; // end export * from "./types-taler-common.js"; -export * from "./types-taler-sync.js"; export * from "./types-taler-wallet-transactions.js"; export * from "./types-taler-wallet.js"; @@ -110,7 +108,5 @@ export * from "./aml/properties.js"; export * from "./aml/reporting.js"; export * from "./iso-3166.js"; -export * from "./iso-4217.js"; -export * from "./iso-639.js"; export * from "./result.js"; diff --git a/packages/taler-util/src/iso-3166.ts b/packages/taler-util/src/iso-3166.ts @@ -592,73 +592,3 @@ export const countryNationalitiesByCode: { [c in CountryCode]: Translator } = { [CountryCode.ZM]: (i18n) => i18n.str`Zambian`, [CountryCode.ZW]: (i18n) => i18n.str`Zimbabwean`, }; - -export const countriesUnicodeFlagByCode: { [c in CountryCode]?: Translator } = { - [CountryCode.AF]: (i18n) => i18n.str`\ud83c\udde6\ud83c\uddeb`, - [CountryCode.AL]: (i18n) => i18n.str`\ud83c\udde6\ud83c\uddf1`, - [CountryCode.DZ]: (i18n) => i18n.str`\ud83c\udde9\ud83c\uddff`, - [CountryCode.US]: (i18n) => i18n.str`\ud83c\uddfa\ud83c\uddf8`, - [CountryCode.AD]: (i18n) => i18n.str`\ud83c\udde6\ud83c\udde9`, - [CountryCode.AO]: (i18n) => i18n.str`\ud83c\udde6\ud83c\uddf4`, - [CountryCode.AG]: (i18n) => i18n.str`\ud83c\udde6\ud83c\uddec`, - [CountryCode.AR]: (i18n) => i18n.str`\ud83c\udde6\ud83c\uddf7`, - [CountryCode.AM]: (i18n) => i18n.str`\ud83c\udde6\ud83c\uddf2`, - [CountryCode.AU]: (i18n) => i18n.str`\ud83c\udde6\ud83c\uddfa`, - [CountryCode.AT]: (i18n) => i18n.str`\ud83c\udde6\ud83c\uddf9`, - [CountryCode.AZ]: (i18n) => i18n.str`\ud83c\udde6\ud83c\uddff`, - [CountryCode.BS]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddf8`, - [CountryCode.BH]: (i18n) => i18n.str`\ud83c\udde7\ud83c\udded`, - [CountryCode.BD]: (i18n) => i18n.str`\ud83c\udde7\ud83c\udde9`, - [CountryCode.BB]: (i18n) => i18n.str`\ud83c\udde7\ud83c\udde7`, - [CountryCode.BW]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddfc`, - [CountryCode.BY]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddfe`, - [CountryCode.BE]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddea`, - [CountryCode.BZ]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddff`, - [CountryCode.BJ]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddef`, - [CountryCode.BT]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddf9`, - [CountryCode.BO]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddf4`, - [CountryCode.BA]: (i18n) => i18n.str`\ud83c\udde7\ud83c\udde6`, - [CountryCode.BR]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddf7`, - [CountryCode.GB]: (i18n) => i18n.str`\ud83c\uddec\ud83c\udde7`, - [CountryCode.BN]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddf3`, - [CountryCode.BG]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddec`, - [CountryCode.BF]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddeb`, - [CountryCode.MM]: (i18n) => i18n.str`\ud83c\uddf2\ud83c\uddf2`, - [CountryCode.BI]: (i18n) => i18n.str`\ud83c\udde7\ud83c\uddee`, - [CountryCode.KH]: (i18n) => i18n.str`\ud83c\uddf0\ud83c\udded`, - [CountryCode.CM]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddf2`, - [CountryCode.CA]: (i18n) => i18n.str`\ud83c\udde8\ud83c\udde6`, - [CountryCode.CV]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddfb`, - [CountryCode.CF]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddeb`, - [CountryCode.TD]: (i18n) => i18n.str`\ud83c\udde9\ud83c\uddff`, - [CountryCode.CL]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddf1`, - [CountryCode.CN]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddf3`, - [CountryCode.CO]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddf4`, - [CountryCode.KM]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddf2`, - [CountryCode.CD]: (i18n) => i18n.str`\ud83c\udde8\ud83c\udde9`, - [CountryCode.CG]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddec`, - [CountryCode.CR]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddf7`, - [CountryCode.HR]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddfb`, - [CountryCode.CU]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddfa`, - [CountryCode.CY]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddfe`, - [CountryCode.CZ]: (i18n) => i18n.str`\ud83c\udde8\ud83c\uddff`, - [CountryCode.DK]: (i18n) => i18n.str`\ud83c\udde9\ud83c\uddf0`, - [CountryCode.DJ]: (i18n) => i18n.str`\ud83c\udde9\ud83c\uddef`, - [CountryCode.DO]: (i18n) => i18n.str`\ud83c\udde9\ud83c\uddf4`, - [CountryCode.NL]: (i18n) => i18n.str`\ud83c\uddf3\ud83c\uddf1`, - [CountryCode.TL]: (i18n) => i18n.str`\ud83c\uddf9\ud83c\uddf1`, - [CountryCode.EC]: (i18n) => i18n.str`\ud83c\uddea\ud83c\udde8`, - [CountryCode.EG]: (i18n) => i18n.str`\ud83c\uddea\ud83c\uddec`, - [CountryCode.AE]: (i18n) => i18n.str`\ud83c\udde6\ud83c\uddea`, - [CountryCode.GQ]: (i18n) => i18n.str`\ud83c\uddec\ud83c\uddf6`, - [CountryCode.ER]: (i18n) => i18n.str`\ud83c\uddea\ud83c\uddf7`, - [CountryCode.EE]: (i18n) => i18n.str`\ud83c\uddea\ud83c\uddea`, - [CountryCode.ET]: (i18n) => i18n.str`\ud83c\uddea\ud83c\uddf9`, - [CountryCode.FJ]: (i18n) => i18n.str`\ud83c\uddeb\ud83c\uddef`, - [CountryCode.PH]: (i18n) => i18n.str`\ud83c\uddf5\ud83c\udded`, - [CountryCode.FI]: (i18n) => i18n.str`\ud83c\uddeb\ud83c\uddee`, - [CountryCode.FR]: (i18n) => i18n.str`\ud83c\uddeb\ud83c\uddf7`, - [CountryCode.GA]: (i18n) => i18n.str`\ud83c\uddec\ud83c\udde6`, - [CountryCode.GM]: (i18n) => i18n.str`\ud83c\uddec\ud83c\uddf2`, - [CountryCode.GE]: (i18n) => i18n.str`\ud83c\uddec\ud83c\uddea`, -}; diff --git a/packages/taler-util/src/iso-4217.ts b/packages/taler-util/src/iso-4217.ts @@ -1,532 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 { Translator } from "./i18n.js"; - -// From https://en.wikipedia.org/wiki/ISO_4217 - -export const enum CurrencyCode { - AED, - AFN, - ALL, - AMD, - ANG, - AOA, - ARS, - AUD, - AWG, - AZN, - BAM, - BBD, - BDT, - BGN, - BHD, - BIF, - BMD, - BND, - BOB, - BOV, - BRL, - BSD, - BTN, - BWP, - BYN, - BZD, - CAD, - CDF, - CHE, - CHF, - CHW, - CLF, - CLP, - CNY, - COP, - COU, - CRC, - CUP, - CVE, - CZK, - DJF, - DKK, - DOP, - DZD, - EGP, - ERN, - ETB, - EUR, - FJD, - FKP, - GBP, - GEL, - GHS, - GIP, - GMD, - GNF, - GTQ, - GYD, - HKD, - HNL, - HTG, - HUF, - IDR, - ILS, - INR, - IQD, - IRR, - ISK, - JMD, - JOD, - JPY, - KES, - KGS, - KHR, - KMF, - KPW, - KRW, - KWD, - KYD, - KZT, - LAK, - LBP, - LKR, - LRD, - LSL, - LYD, - MAD, - MDL, - MGA, - MKD, - MMK, - MNT, - MOP, - MRU, - MUR, - MVR, - MWK, - MXN, - MXV, - MYR, - MZN, - NAD, - NGN, - NIO, - NOK, - NPR, - NZD, - OMR, - PAB, - PEN, - PGK, - PHP, - PKR, - PLN, - PYG, - QAR, - RON, - RSD, - RUB, - RWF, - SAR, - SBD, - SCR, - SDG, - SEK, - SGD, - SHP, - SLE, - SOS, - SRD, - SSP, - STN, - SVC, - SYP, - SZL, - THB, - TJS, - TMT, - TND, - TOP, - TRY, - TTD, - TWD, - TZS, - UAH, - UGX, - USD, - USN, - UYI, - UYU, - UYW, - UZS, - VED, - VES, - VND, - VUV, - WST, - XAF, - XCD, - XOF, - XPF, - XSU, - YER, - ZAR, - ZMW, - ZWG, -} - -export const currencyInfoByCode: { - [c in CurrencyCode]: { - c: number; //numeric code - d: number; //number of decimal digits - }; -} = { - [CurrencyCode.AED]: { c: 784, d: 2 }, - [CurrencyCode.AFN]: { c: 971, d: 2 }, - [CurrencyCode.ALL]: { c: 8, d: 2 }, - [CurrencyCode.AMD]: { c: 51, d: 2 }, - [CurrencyCode.ANG]: { c: 532, d: 2 }, - [CurrencyCode.AOA]: { c: 973, d: 2 }, - [CurrencyCode.ARS]: { c: 32, d: 2 }, - [CurrencyCode.AUD]: { c: 36, d: 2 }, - [CurrencyCode.AWG]: { c: 533, d: 2 }, - [CurrencyCode.AZN]: { c: 944, d: 2 }, - [CurrencyCode.BAM]: { c: 977, d: 2 }, - [CurrencyCode.BBD]: { c: 52, d: 2 }, - [CurrencyCode.BDT]: { c: 50, d: 2 }, - [CurrencyCode.BGN]: { c: 975, d: 2 }, - [CurrencyCode.BHD]: { c: 48, d: 3 }, - [CurrencyCode.BIF]: { c: 108, d: 0 }, - [CurrencyCode.BMD]: { c: 60, d: 2 }, - [CurrencyCode.BND]: { c: 96, d: 2 }, - [CurrencyCode.BOB]: { c: 68, d: 2 }, - [CurrencyCode.BOV]: { c: 984, d: 2 }, - [CurrencyCode.BRL]: { c: 986, d: 2 }, - [CurrencyCode.BSD]: { c: 44, d: 2 }, - [CurrencyCode.BTN]: { c: 64, d: 2 }, - [CurrencyCode.BWP]: { c: 72, d: 2 }, - [CurrencyCode.BYN]: { c: 933, d: 2 }, - [CurrencyCode.BZD]: { c: 84, d: 2 }, - [CurrencyCode.CAD]: { c: 124, d: 2 }, - [CurrencyCode.CDF]: { c: 976, d: 2 }, - [CurrencyCode.CHE]: { c: 947, d: 2 }, - [CurrencyCode.CHF]: { c: 756, d: 2 }, - [CurrencyCode.CHW]: { c: 948, d: 2 }, - [CurrencyCode.CLF]: { c: 990, d: 4 }, - [CurrencyCode.CLP]: { c: 152, d: 0 }, - [CurrencyCode.CNY]: { c: 156, d: 2 }, - [CurrencyCode.COP]: { c: 170, d: 2 }, - [CurrencyCode.COU]: { c: 970, d: 2 }, - [CurrencyCode.CRC]: { c: 188, d: 2 }, - [CurrencyCode.CUP]: { c: 192, d: 2 }, - [CurrencyCode.CVE]: { c: 132, d: 2 }, - [CurrencyCode.CZK]: { c: 203, d: 2 }, - [CurrencyCode.DJF]: { c: 262, d: 0 }, - [CurrencyCode.DKK]: { c: 208, d: 2 }, - [CurrencyCode.DOP]: { c: 214, d: 2 }, - [CurrencyCode.DZD]: { c: 12, d: 2 }, - [CurrencyCode.EGP]: { c: 818, d: 2 }, - [CurrencyCode.ERN]: { c: 232, d: 2 }, - [CurrencyCode.ETB]: { c: 230, d: 2 }, - [CurrencyCode.EUR]: { c: 978, d: 2 }, - [CurrencyCode.FJD]: { c: 242, d: 2 }, - [CurrencyCode.FKP]: { c: 238, d: 2 }, - [CurrencyCode.GBP]: { c: 826, d: 2 }, - [CurrencyCode.GEL]: { c: 981, d: 2 }, - [CurrencyCode.GHS]: { c: 936, d: 2 }, - [CurrencyCode.GIP]: { c: 292, d: 2 }, - [CurrencyCode.GMD]: { c: 270, d: 2 }, - [CurrencyCode.GNF]: { c: 324, d: 0 }, - [CurrencyCode.GTQ]: { c: 320, d: 2 }, - [CurrencyCode.GYD]: { c: 328, d: 2 }, - [CurrencyCode.HKD]: { c: 344, d: 2 }, - [CurrencyCode.HNL]: { c: 340, d: 2 }, - [CurrencyCode.HTG]: { c: 332, d: 2 }, - [CurrencyCode.HUF]: { c: 348, d: 2 }, - [CurrencyCode.IDR]: { c: 360, d: 2 }, - [CurrencyCode.ILS]: { c: 376, d: 2 }, - [CurrencyCode.INR]: { c: 356, d: 2 }, - [CurrencyCode.IQD]: { c: 368, d: 3 }, - [CurrencyCode.IRR]: { c: 364, d: 2 }, - [CurrencyCode.ISK]: { c: 352, d: 0 }, - [CurrencyCode.JMD]: { c: 388, d: 2 }, - [CurrencyCode.JOD]: { c: 400, d: 3 }, - [CurrencyCode.JPY]: { c: 392, d: 0 }, - [CurrencyCode.KES]: { c: 404, d: 2 }, - [CurrencyCode.KGS]: { c: 417, d: 2 }, - [CurrencyCode.KHR]: { c: 116, d: 2 }, - [CurrencyCode.KMF]: { c: 174, d: 0 }, - [CurrencyCode.KPW]: { c: 408, d: 2 }, - [CurrencyCode.KRW]: { c: 410, d: 0 }, - [CurrencyCode.KWD]: { c: 414, d: 3 }, - [CurrencyCode.KYD]: { c: 136, d: 2 }, - [CurrencyCode.KZT]: { c: 398, d: 2 }, - [CurrencyCode.LAK]: { c: 418, d: 2 }, - [CurrencyCode.LBP]: { c: 422, d: 2 }, - [CurrencyCode.LKR]: { c: 144, d: 2 }, - [CurrencyCode.LRD]: { c: 430, d: 2 }, - [CurrencyCode.LSL]: { c: 426, d: 2 }, - [CurrencyCode.LYD]: { c: 434, d: 3 }, - [CurrencyCode.MAD]: { c: 504, d: 2 }, - [CurrencyCode.MDL]: { c: 498, d: 2 }, - [CurrencyCode.MGA]: { c: 969, d: 2 }, - [CurrencyCode.MKD]: { c: 807, d: 2 }, - [CurrencyCode.MMK]: { c: 104, d: 2 }, - [CurrencyCode.MNT]: { c: 496, d: 2 }, - [CurrencyCode.MOP]: { c: 446, d: 2 }, - [CurrencyCode.MRU]: { c: 929, d: 2 }, - [CurrencyCode.MUR]: { c: 480, d: 2 }, - [CurrencyCode.MVR]: { c: 462, d: 2 }, - [CurrencyCode.MWK]: { c: 454, d: 2 }, - [CurrencyCode.MXN]: { c: 484, d: 2 }, - [CurrencyCode.MXV]: { c: 979, d: 2 }, - [CurrencyCode.MYR]: { c: 458, d: 2 }, - [CurrencyCode.MZN]: { c: 943, d: 2 }, - [CurrencyCode.NAD]: { c: 516, d: 2 }, - [CurrencyCode.NGN]: { c: 566, d: 2 }, - [CurrencyCode.NIO]: { c: 558, d: 2 }, - [CurrencyCode.NOK]: { c: 578, d: 2 }, - [CurrencyCode.NPR]: { c: 524, d: 2 }, - [CurrencyCode.NZD]: { c: 554, d: 2 }, - [CurrencyCode.OMR]: { c: 512, d: 3 }, - [CurrencyCode.PAB]: { c: 590, d: 2 }, - [CurrencyCode.PEN]: { c: 604, d: 2 }, - [CurrencyCode.PGK]: { c: 598, d: 2 }, - [CurrencyCode.PHP]: { c: 608, d: 2 }, - [CurrencyCode.PKR]: { c: 586, d: 2 }, - [CurrencyCode.PLN]: { c: 985, d: 2 }, - [CurrencyCode.PYG]: { c: 600, d: 0 }, - [CurrencyCode.QAR]: { c: 634, d: 2 }, - [CurrencyCode.RON]: { c: 946, d: 2 }, - [CurrencyCode.RSD]: { c: 941, d: 2 }, - [CurrencyCode.RUB]: { c: 643, d: 2 }, - [CurrencyCode.RWF]: { c: 646, d: 0 }, - [CurrencyCode.SAR]: { c: 682, d: 2 }, - [CurrencyCode.SBD]: { c: 90, d: 2 }, - [CurrencyCode.SCR]: { c: 690, d: 2 }, - [CurrencyCode.SDG]: { c: 938, d: 2 }, - [CurrencyCode.SEK]: { c: 752, d: 2 }, - [CurrencyCode.SGD]: { c: 702, d: 2 }, - [CurrencyCode.SHP]: { c: 654, d: 2 }, - [CurrencyCode.SLE]: { c: 925, d: 2 }, - [CurrencyCode.SOS]: { c: 706, d: 2 }, - [CurrencyCode.SRD]: { c: 968, d: 2 }, - [CurrencyCode.SSP]: { c: 728, d: 2 }, - [CurrencyCode.STN]: { c: 930, d: 2 }, - [CurrencyCode.SVC]: { c: 222, d: 2 }, - [CurrencyCode.SYP]: { c: 760, d: 2 }, - [CurrencyCode.SZL]: { c: 748, d: 2 }, - [CurrencyCode.THB]: { c: 764, d: 2 }, - [CurrencyCode.TJS]: { c: 972, d: 2 }, - [CurrencyCode.TMT]: { c: 934, d: 2 }, - [CurrencyCode.TND]: { c: 788, d: 3 }, - [CurrencyCode.TOP]: { c: 776, d: 2 }, - [CurrencyCode.TRY]: { c: 949, d: 2 }, - [CurrencyCode.TTD]: { c: 780, d: 2 }, - [CurrencyCode.TWD]: { c: 901, d: 2 }, - [CurrencyCode.TZS]: { c: 834, d: 2 }, - [CurrencyCode.UAH]: { c: 980, d: 2 }, - [CurrencyCode.UGX]: { c: 800, d: 0 }, - [CurrencyCode.USD]: { c: 840, d: 2 }, - [CurrencyCode.USN]: { c: 997, d: 2 }, - [CurrencyCode.UYI]: { c: 940, d: 0 }, - [CurrencyCode.UYU]: { c: 858, d: 2 }, - [CurrencyCode.UYW]: { c: 927, d: 4 }, - [CurrencyCode.UZS]: { c: 860, d: 2 }, - [CurrencyCode.VED]: { c: 926, d: 2 }, - [CurrencyCode.VES]: { c: 928, d: 2 }, - [CurrencyCode.VND]: { c: 704, d: 0 }, - [CurrencyCode.VUV]: { c: 548, d: 0 }, - [CurrencyCode.WST]: { c: 882, d: 2 }, - [CurrencyCode.XAF]: { c: 950, d: 0 }, - [CurrencyCode.XCD]: { c: 951, d: 2 }, - [CurrencyCode.XOF]: { c: 952, d: 0 }, - [CurrencyCode.XPF]: { c: 953, d: 0 }, - [CurrencyCode.XSU]: { c: 994, d: 0 }, - [CurrencyCode.YER]: { c: 886, d: 2 }, - [CurrencyCode.ZAR]: { c: 710, d: 2 }, - [CurrencyCode.ZMW]: { c: 967, d: 2 }, - [CurrencyCode.ZWG]: { c: 924, d: 2 }, -}; - -export const currencyNamesByCode: { [c in CurrencyCode]: Translator } = { - [CurrencyCode.AED]: (i18n) => i18n.str`UAE Dirham`, - [CurrencyCode.AFN]: (i18n) => i18n.str`Afghani`, - [CurrencyCode.ALL]: (i18n) => i18n.str`Lek`, - [CurrencyCode.AMD]: (i18n) => i18n.str`Armenian Dram`, - [CurrencyCode.ANG]: (i18n) => i18n.str`Netherlands Antillean Guilder`, - [CurrencyCode.AOA]: (i18n) => i18n.str`Kwanza`, - [CurrencyCode.ARS]: (i18n) => i18n.str`Argentine Peso`, - [CurrencyCode.AUD]: (i18n) => i18n.str`Australian Dollar`, - [CurrencyCode.AWG]: (i18n) => i18n.str`Aruban Florin`, - [CurrencyCode.AZN]: (i18n) => i18n.str`Azerbaijan Manat`, - [CurrencyCode.BAM]: (i18n) => i18n.str`Convertible Mark`, - [CurrencyCode.BBD]: (i18n) => i18n.str`Barbados Dollar`, - [CurrencyCode.BDT]: (i18n) => i18n.str`Taka`, - [CurrencyCode.BGN]: (i18n) => i18n.str`Bulgarian Lev`, - [CurrencyCode.BHD]: (i18n) => i18n.str`Bahraini Dinar`, - [CurrencyCode.BIF]: (i18n) => i18n.str`Burundi Franc`, - [CurrencyCode.BMD]: (i18n) => i18n.str`Bermudian Dollar`, - [CurrencyCode.BND]: (i18n) => i18n.str`Brunei Dollar`, - [CurrencyCode.BOB]: (i18n) => i18n.str`Boliviano`, - [CurrencyCode.BOV]: (i18n) => i18n.str`Mvdol`, - [CurrencyCode.BRL]: (i18n) => i18n.str`Brazilian Real`, - [CurrencyCode.BSD]: (i18n) => i18n.str`Bahamian Dollar`, - [CurrencyCode.BTN]: (i18n) => i18n.str`Ngultrum`, - [CurrencyCode.BWP]: (i18n) => i18n.str`Pula`, - [CurrencyCode.BYN]: (i18n) => i18n.str`Belarusian Ruble`, - [CurrencyCode.BZD]: (i18n) => i18n.str`Belize Dollar`, - [CurrencyCode.CAD]: (i18n) => i18n.str`Canadian Dollar`, - [CurrencyCode.CDF]: (i18n) => i18n.str`Congolese Franc`, - [CurrencyCode.CHE]: (i18n) => i18n.str`WIR Euro`, - [CurrencyCode.CHF]: (i18n) => i18n.str`Swiss Franc`, - [CurrencyCode.CHW]: (i18n) => i18n.str`WIR Franc`, - [CurrencyCode.CLF]: (i18n) => i18n.str`Unidad de Fomento`, - [CurrencyCode.CLP]: (i18n) => i18n.str`Chilean Peso`, - [CurrencyCode.CNY]: (i18n) => i18n.str`Yuan Renminbi`, - [CurrencyCode.COP]: (i18n) => i18n.str`Colombian Peso`, - [CurrencyCode.COU]: (i18n) => i18n.str`Unidad de Valor Real`, - [CurrencyCode.CRC]: (i18n) => i18n.str`Costa Rican Colon`, - [CurrencyCode.CUP]: (i18n) => i18n.str`Cuban Peso`, - [CurrencyCode.CVE]: (i18n) => i18n.str`Cabo Verde Escudo`, - [CurrencyCode.CZK]: (i18n) => i18n.str`Czech Koruna`, - [CurrencyCode.DJF]: (i18n) => i18n.str`Djibouti Franc`, - [CurrencyCode.DKK]: (i18n) => i18n.str`Danish Krone`, - [CurrencyCode.DOP]: (i18n) => i18n.str`Dominican Peso`, - [CurrencyCode.DZD]: (i18n) => i18n.str`Algerian Dinar`, - [CurrencyCode.EGP]: (i18n) => i18n.str`Egyptian Pound`, - [CurrencyCode.ERN]: (i18n) => i18n.str`Nakfa`, - [CurrencyCode.ETB]: (i18n) => i18n.str`Ethiopian Birr`, - [CurrencyCode.EUR]: (i18n) => i18n.str`Euro`, - [CurrencyCode.FJD]: (i18n) => i18n.str`Fiji Dollar`, - [CurrencyCode.FKP]: (i18n) => i18n.str`Falkland Islands Pound`, - [CurrencyCode.GBP]: (i18n) => i18n.str`Pound Sterling`, - [CurrencyCode.GEL]: (i18n) => i18n.str`Lari`, - [CurrencyCode.GHS]: (i18n) => i18n.str`Ghana Cedi`, - [CurrencyCode.GIP]: (i18n) => i18n.str`Gibraltar Pound`, - [CurrencyCode.GMD]: (i18n) => i18n.str`Dalasi`, - [CurrencyCode.GNF]: (i18n) => i18n.str`Guinean Franc`, - [CurrencyCode.GTQ]: (i18n) => i18n.str`Quetzal`, - [CurrencyCode.GYD]: (i18n) => i18n.str`Guyana Dollar`, - [CurrencyCode.HKD]: (i18n) => i18n.str`Hong Kong Dollar`, - [CurrencyCode.HNL]: (i18n) => i18n.str`Lempira`, - [CurrencyCode.HTG]: (i18n) => i18n.str`Gourde`, - [CurrencyCode.HUF]: (i18n) => i18n.str`Forint`, - [CurrencyCode.IDR]: (i18n) => i18n.str`Rupiah`, - [CurrencyCode.ILS]: (i18n) => i18n.str`New Israeli Sheqel`, - [CurrencyCode.INR]: (i18n) => i18n.str`Indian Rupee`, - [CurrencyCode.IQD]: (i18n) => i18n.str`Iraqi Dinar`, - [CurrencyCode.IRR]: (i18n) => i18n.str`Iranian Rial`, - [CurrencyCode.ISK]: (i18n) => i18n.str`Iceland Krona`, - [CurrencyCode.JMD]: (i18n) => i18n.str`Jamaican Dollar`, - [CurrencyCode.JOD]: (i18n) => i18n.str`Jordanian Dinar`, - [CurrencyCode.JPY]: (i18n) => i18n.str`Yen`, - [CurrencyCode.KES]: (i18n) => i18n.str`Kenyan Shilling`, - [CurrencyCode.KGS]: (i18n) => i18n.str`Som`, - [CurrencyCode.KHR]: (i18n) => i18n.str`Riel`, - [CurrencyCode.KMF]: (i18n) => i18n.str`Comorian Franc `, - [CurrencyCode.KPW]: (i18n) => i18n.str`North Korean Won`, - [CurrencyCode.KRW]: (i18n) => i18n.str`Won`, - [CurrencyCode.KWD]: (i18n) => i18n.str`Kuwaiti Dinar`, - [CurrencyCode.KYD]: (i18n) => i18n.str`Cayman Islands Dollar`, - [CurrencyCode.KZT]: (i18n) => i18n.str`Tenge`, - [CurrencyCode.LAK]: (i18n) => i18n.str`Lao Kip`, - [CurrencyCode.LBP]: (i18n) => i18n.str`Lebanese Pound`, - [CurrencyCode.LKR]: (i18n) => i18n.str`Sri Lanka Rupee`, - [CurrencyCode.LRD]: (i18n) => i18n.str`Liberian Dollar`, - [CurrencyCode.LSL]: (i18n) => i18n.str`Loti`, - [CurrencyCode.LYD]: (i18n) => i18n.str`Libyan Dinar`, - [CurrencyCode.MAD]: (i18n) => i18n.str`Moroccan Dirham`, - [CurrencyCode.MDL]: (i18n) => i18n.str`Moldovan Leu`, - [CurrencyCode.MGA]: (i18n) => i18n.str`Malagasy Ariary`, - [CurrencyCode.MKD]: (i18n) => i18n.str`Denar`, - [CurrencyCode.MMK]: (i18n) => i18n.str`Kyat`, - [CurrencyCode.MNT]: (i18n) => i18n.str`Tugrik`, - [CurrencyCode.MOP]: (i18n) => i18n.str`Pataca`, - [CurrencyCode.MRU]: (i18n) => i18n.str`Ouguiya`, - [CurrencyCode.MUR]: (i18n) => i18n.str`Mauritius Rupee`, - [CurrencyCode.MVR]: (i18n) => i18n.str`Rufiyaa`, - [CurrencyCode.MWK]: (i18n) => i18n.str`Malawi Kwacha`, - [CurrencyCode.MXN]: (i18n) => i18n.str`Mexican Peso`, - [CurrencyCode.MXV]: (i18n) => i18n.str`Mexican Unidad de Inversion (UDI)`, - [CurrencyCode.MYR]: (i18n) => i18n.str`Malaysian Ringgit`, - [CurrencyCode.MZN]: (i18n) => i18n.str`Mozambique Metical`, - [CurrencyCode.NAD]: (i18n) => i18n.str`Namibia Dollar`, - [CurrencyCode.NGN]: (i18n) => i18n.str`Naira`, - [CurrencyCode.NIO]: (i18n) => i18n.str`Cordoba Oro`, - [CurrencyCode.NOK]: (i18n) => i18n.str`Norwegian Krone`, - [CurrencyCode.NPR]: (i18n) => i18n.str`Nepalese Rupee`, - [CurrencyCode.NZD]: (i18n) => i18n.str`New Zealand Dollar`, - [CurrencyCode.OMR]: (i18n) => i18n.str`Rial Omani`, - [CurrencyCode.PAB]: (i18n) => i18n.str`Balboa`, - [CurrencyCode.PEN]: (i18n) => i18n.str`Sol`, - [CurrencyCode.PGK]: (i18n) => i18n.str`Kina`, - [CurrencyCode.PHP]: (i18n) => i18n.str`Philippine Peso`, - [CurrencyCode.PKR]: (i18n) => i18n.str`Pakistan Rupee`, - [CurrencyCode.PLN]: (i18n) => i18n.str`Zloty`, - [CurrencyCode.PYG]: (i18n) => i18n.str`Guarani`, - [CurrencyCode.QAR]: (i18n) => i18n.str`Qatari Rial`, - [CurrencyCode.RON]: (i18n) => i18n.str`Romanian Leu`, - [CurrencyCode.RSD]: (i18n) => i18n.str`Serbian Dinar`, - [CurrencyCode.RUB]: (i18n) => i18n.str`Russian Ruble`, - [CurrencyCode.RWF]: (i18n) => i18n.str`Rwanda Franc`, - [CurrencyCode.SAR]: (i18n) => i18n.str`Saudi Riyal`, - [CurrencyCode.SBD]: (i18n) => i18n.str`Solomon Islands Dollar`, - [CurrencyCode.SCR]: (i18n) => i18n.str`Seychelles Rupee`, - [CurrencyCode.SDG]: (i18n) => i18n.str`Sudanese Pound`, - [CurrencyCode.SEK]: (i18n) => i18n.str`Swedish Krona`, - [CurrencyCode.SGD]: (i18n) => i18n.str`Singapore Dollar`, - [CurrencyCode.SHP]: (i18n) => i18n.str`Saint Helena Pound`, - [CurrencyCode.SLE]: (i18n) => i18n.str`Leone`, - [CurrencyCode.SOS]: (i18n) => i18n.str`Somali Shilling`, - [CurrencyCode.SRD]: (i18n) => i18n.str`Surinam Dollar`, - [CurrencyCode.SSP]: (i18n) => i18n.str`South Sudanese Pound`, - [CurrencyCode.STN]: (i18n) => i18n.str`Dobra`, - [CurrencyCode.SVC]: (i18n) => i18n.str`El Salvador Colon`, - [CurrencyCode.SYP]: (i18n) => i18n.str`Syrian Pound`, - [CurrencyCode.SZL]: (i18n) => i18n.str`Lilangeni`, - [CurrencyCode.THB]: (i18n) => i18n.str`Baht`, - [CurrencyCode.TJS]: (i18n) => i18n.str`Somoni`, - [CurrencyCode.TMT]: (i18n) => i18n.str`Turkmenistan New Manat`, - [CurrencyCode.TND]: (i18n) => i18n.str`Tunisian Dinar`, - [CurrencyCode.TOP]: (i18n) => i18n.str`Pa’anga`, - [CurrencyCode.TRY]: (i18n) => i18n.str`Turkish Lira`, - [CurrencyCode.TTD]: (i18n) => i18n.str`Trinidad and Tobago Dollar`, - [CurrencyCode.TWD]: (i18n) => i18n.str`New Taiwan Dollar`, - [CurrencyCode.TZS]: (i18n) => i18n.str`Tanzanian Shilling`, - [CurrencyCode.UAH]: (i18n) => i18n.str`Hryvnia`, - [CurrencyCode.UGX]: (i18n) => i18n.str`Uganda Shilling`, - [CurrencyCode.USD]: (i18n) => i18n.str`US Dollar`, - [CurrencyCode.USN]: (i18n) => i18n.str`US Dollar (Next day)`, - [CurrencyCode.UYI]: (i18n) => - i18n.str`Uruguay Peso en Unidades Indexadas (UI)`, - [CurrencyCode.UYU]: (i18n) => i18n.str`Peso Uruguayo`, - [CurrencyCode.UYW]: (i18n) => i18n.str`Unidad Previsional`, - [CurrencyCode.UZS]: (i18n) => i18n.str`Uzbekistan Sum`, - [CurrencyCode.VED]: (i18n) => i18n.str`Bolívar Soberano`, - [CurrencyCode.VES]: (i18n) => i18n.str`Bolívar Soberano`, - [CurrencyCode.VND]: (i18n) => i18n.str`Dong`, - [CurrencyCode.VUV]: (i18n) => i18n.str`Vatu`, - [CurrencyCode.WST]: (i18n) => i18n.str`Tala`, - [CurrencyCode.XAF]: (i18n) => i18n.str`CFA Franc BEAC`, - [CurrencyCode.XCD]: (i18n) => i18n.str`East Caribbean Dollar`, - [CurrencyCode.XOF]: (i18n) => i18n.str`CFA Franc BCEAO`, - [CurrencyCode.XPF]: (i18n) => i18n.str`CFP Franc`, - [CurrencyCode.XSU]: (i18n) => i18n.str`Sucre`, - [CurrencyCode.YER]: (i18n) => i18n.str`Yemeni Rial`, - [CurrencyCode.ZAR]: (i18n) => i18n.str`Rand`, - [CurrencyCode.ZMW]: (i18n) => i18n.str`Zambian Kwacha`, - [CurrencyCode.ZWG]: (i18n) => i18n.str`Zimbabwe Gold`, -}; diff --git a/packages/taler-util/src/iso-639.ts b/packages/taler-util/src/iso-639.ts @@ -1,1246 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 { Translator } from "./i18n.js"; - -/** - * This was taken from https://raw.githubusercontent.com/umpirsky/language-list/refs/heads/master/data/ak/language.txt - * - * FIXME: Check with ISO standard - */ -export const enum LangCode { - aa, - ab, - ace, - ach, - ada, - ady, - ae, - aeb, - af, - afh, - agq, - ain, - ak, - akk, - akz, - ale, - aln, - alt, - am, - an, - ang, - anp, - ar_001, - ar, - arc, - arn, - aro, - arp, - arq, - arw, - ary, - arz, - asa, - as, - ase, - ast, - av, - avk, - awa, - ay, - az, - azb, - ba, - bal, - ban, - bar, - bas, - bax, - bbc, - bbj, - be, - bej, - bem, - bew, - bez, - bfd, - bfq, - bg, - bho, - bi, - bik, - bin, - bjn, - bkm, - bla, - bm, - bn, - bo, - bpy, - bqi, - bra, - br, - brh, - brx, - bs, - bss, - bua, - bug, - bum, - byn, - byv, - ca, - cad, - car, - cay, - cch, - ceb, - ce, - cgg, - chb, - ch, - chg, - chk, - chm, - chn, - cho, - chp, - chr, - chy, - ckb, - co, - cop, - cps, - cr, - crh, - csb, - cs, - cu, - cv, - cy, - da, - dak, - dar, - dav, - de_AT, - de_CH, - de, - del, - den, - dgr, - din, - dje, - doi, - dsb, - dtp, - dua, - dum, - dv, - dyo, - dyu, - dz, - dzg, - ebu, - ee, - efi, - egl, - egy, - eka, - el, - elx, - en_AU, - en, - en_CA, - en_GB, - enm, - en_US, - eo, - es_419, - es_ES, - es_MX, - es, - esu, - et, - eu, - ewo, - ext, - fan, - fa, - fat, - ff, - fi, - fil, - fit, - fj, - fo, - fon, - fr_CA, - frc, - fr_CH, - fr, - frm, - fro, - frp, - frr, - frs, - fur, - fy, - gaa, - gag, - ga, - gan, - gay, - gba, - gbz, - gd, - gez, - gil, - gl, - glk, - gmh, - gn, - goh, - gom, - gon, - gor, - got, - grb, - grc, - gsw, - guc, - gu, - gur, - guz, - gv, - gwi, - ha, - hai, - hak, - haw, - he, - hif, - hi, - hil, - hit, - hmn, - ho, - hr, - hsb, - hsn, - ht, - hu, - hup, - hy, - hz, - ia, - iba, - ibb, - id, - ie, - ig, - ii, - ik, - ilo, - inh, - io, - is, - it, - iu, - izh, - ja, - jam, - jbo, - jgo, - jmc, - jpr, - jrb, - jut, - jv, - kaa, - kab, - kac, - ka, - kaj, - kam, - kaw, - kbd, - kbl, - kcg, - kde, - kea, - ken, - kfo, - kg, - kgp, - kha, - kho, - khq, - khw, - ki, - kiu, - kj, - kkj, - kk, - kl, - kln, - kmb, - km, - kn, - koi, - kok, - ko, - kos, - kpe, - krc, - kri, - krj, - kr, - krl, - kru, - ksb, - ksf, - ksh, - ks, - ku, - kum, - kut, - kv, - kw, - ky, - lad, - lag, - lah, - la, - lam, - lb, - lez, - lfn, - lg, - lij, - li, - liv, - lkt, - lmo, - ln, - lo, - lol, - loz, - ltg, - lt, - lua, - lui, - lu, - lun, - luo, - lus, - luy, - lv, - lzh, - lzz, - mad, - maf, - mag, - mai, - mak, - man, - mas, - mde, - mdf, - mdr, - men, - mer, - mfe, - mga, - mgh, - mg, - mgo, - mh, - mic, - mi, - min, - mk, - ml, - mnc, - mni, - mn, - moh, - mos, - mrj, - mr, - ms, - mt, - mua, - mul, - mus, - mwl, - mwr, - mwv, - my, - mye, - myv, - mzn, - na, - nan, - nap, - naq, - nb, - nd, - nds, - ne, - new, - ng, - nia, - niu, - njo, - nl_BE, - nl, - nmg, - nnh, - nn, - nog, - non, - no, - nov, - nqo, - nr, - nso, - nus, - nv, - nwc, - nym, - nyn, - ny, - nyo, - nzi, - oc, - oj, - om, - or, - osa, - os, - ota, - pag, - pal, - pam, - pap, - pa, - pau, - pcd, - pdc, - pdt, - peo, - pfl, - phn, - pi, - pl, - pms, - pnt, - pon, - prg, - pro, - ps, - pt_BR, - pt, - pt_PT, - quc, - qug, - qu, - raj, - rap, - rar, - rgn, - rif, - rm, - rn, - rof, - ro_MD, - rom, - root, - ro, - rtm, - rue, - rug, - rup, - ru, - rwk, - rw, - sad, - sah, - sam, - saq, - sa, - sas, - sat, - saz, - sba, - sbp, - scn, - sco, - sc, - sdc, - sd, - see, - seh, - sei, - sel, - se, - ses, - sga, - sg, - sgs, - shi, - shn, - sh, - shu, - sid, - si, - sk, - sli, - sl, - sly, - sma, - smj, - smn, - sm, - sms, - snk, - sn, - sog, - so, - sq, - srn, - srr, - sr, - ss, - ssy, - stq, - st, - suk, - sus, - su, - sux, - sv, - swb, - swc, - sw, - syc, - syr, - szl, - ta, - tcy, - tem, - teo, - ter, - te, - tet, - tg, - th, - tig, - ti, - tiv, - tkl, - tkr, - tk, - tlh, - tli, - tl, - tly, - tmh, - tn, - tog, - to, - tpi, - tr, - tru, - trv, - tsd, - tsi, - ts, - tt, - ttt, - tum, - tvl, - twq, - tw, - ty, - tyv, - tzm, - udm, - uga, - ug, - uk, - umb, - und, - ur, - uz, - vai, - vec, - vep, - ve, - vi, - vls, - vmf, - vot, - vo, - vro, - vun, - wae, - wal, - war, - was, - wa, - wbp, - wo, - wuu, - xal, - xh, - xmf, - xog, - yao, - yap, - yav, - ybb, - yi, - yo, - yrl, - yue, - zap, - za, - zbl, - zea, - zen, - zgh, - zh_Hans, - zh_Hant, - zh, - zun, - zu, - zxx, - zza, -} - -export const langNamesByCode: { [c in LangCode]: Translator } = { - [LangCode.aa]: (i18n) => i18n.str`Afar`, - [LangCode.ab]: (i18n) => i18n.str`Abkhazian`, - [LangCode.ace]: (i18n) => i18n.str`Achinese`, - [LangCode.ach]: (i18n) => i18n.str`Acoli`, - [LangCode.ada]: (i18n) => i18n.str`Adangme`, - [LangCode.ady]: (i18n) => i18n.str`Adyghe`, - [LangCode.ae]: (i18n) => i18n.str`Avestan`, - [LangCode.aeb]: (i18n) => i18n.str`Tunisian Arabic`, - [LangCode.af]: (i18n) => i18n.str`Afrikaans`, - [LangCode.afh]: (i18n) => i18n.str`Afrihili`, - [LangCode.agq]: (i18n) => i18n.str`Aghem`, - [LangCode.ain]: (i18n) => i18n.str`Ainu`, - [LangCode.ak]: (i18n) => i18n.str`Akan`, - [LangCode.akk]: (i18n) => i18n.str`Akkadian`, - [LangCode.akz]: (i18n) => i18n.str`Alabama`, - [LangCode.ale]: (i18n) => i18n.str`Aleut`, - [LangCode.aln]: (i18n) => i18n.str`Gheg Albanian`, - [LangCode.alt]: (i18n) => i18n.str`Southern Altai`, - [LangCode.am]: (i18n) => i18n.str`Amarik`, - [LangCode.an]: (i18n) => i18n.str`Aragonese`, - [LangCode.ang]: (i18n) => i18n.str`Old English`, - [LangCode.anp]: (i18n) => i18n.str`Angika`, - [LangCode.ar_001]: (i18n) => i18n.str`Modern Standard Arabic`, - [LangCode.ar]: (i18n) => i18n.str`Arabik`, - [LangCode.arc]: (i18n) => i18n.str`Aramaic`, - [LangCode.arn]: (i18n) => i18n.str`Mapuche`, - [LangCode.aro]: (i18n) => i18n.str`Araona`, - [LangCode.arp]: (i18n) => i18n.str`Arapaho`, - [LangCode.arq]: (i18n) => i18n.str`Algerian Arabic`, - [LangCode.arw]: (i18n) => i18n.str`Arawak`, - [LangCode.ary]: (i18n) => i18n.str`Moroccan Arabic`, - [LangCode.arz]: (i18n) => i18n.str`Egyptian Arabic`, - [LangCode.asa]: (i18n) => i18n.str`Asu`, - [LangCode.as]: (i18n) => i18n.str`Assamese`, - [LangCode.ase]: (i18n) => i18n.str`American Sign Language`, - [LangCode.ast]: (i18n) => i18n.str`Asturian`, - [LangCode.av]: (i18n) => i18n.str`Avaric`, - [LangCode.avk]: (i18n) => i18n.str`Kotava`, - [LangCode.awa]: (i18n) => i18n.str`Awadhi`, - [LangCode.ay]: (i18n) => i18n.str`Aymara`, - [LangCode.az]: (i18n) => i18n.str`Azerbaijani`, - [LangCode.azb]: (i18n) => i18n.str`South Azerbaijani`, - [LangCode.ba]: (i18n) => i18n.str`Bashkir`, - [LangCode.bal]: (i18n) => i18n.str`Baluchi`, - [LangCode.ban]: (i18n) => i18n.str`Balinese`, - [LangCode.bar]: (i18n) => i18n.str`Bavarian`, - [LangCode.bas]: (i18n) => i18n.str`Basaa`, - [LangCode.bax]: (i18n) => i18n.str`Bamun`, - [LangCode.bbc]: (i18n) => i18n.str`Batak Toba`, - [LangCode.bbj]: (i18n) => i18n.str`Ghomala`, - [LangCode.be]: (i18n) => i18n.str`Belarus kasa`, - [LangCode.bej]: (i18n) => i18n.str`Beja`, - [LangCode.bem]: (i18n) => i18n.str`Bemba`, - [LangCode.bew]: (i18n) => i18n.str`Betawi`, - [LangCode.bez]: (i18n) => i18n.str`Bena`, - [LangCode.bfd]: (i18n) => i18n.str`Bafut`, - [LangCode.bfq]: (i18n) => i18n.str`Badaga`, - [LangCode.bg]: (i18n) => i18n.str`Bɔlgeria kasa`, - [LangCode.bho]: (i18n) => i18n.str`Bhojpuri`, - [LangCode.bi]: (i18n) => i18n.str`Bislama`, - [LangCode.bik]: (i18n) => i18n.str`Bikol`, - [LangCode.bin]: (i18n) => i18n.str`Bini`, - [LangCode.bjn]: (i18n) => i18n.str`Banjar`, - [LangCode.bkm]: (i18n) => i18n.str`Kom`, - [LangCode.bla]: (i18n) => i18n.str`Siksika`, - [LangCode.bm]: (i18n) => i18n.str`Bambara`, - [LangCode.bn]: (i18n) => i18n.str`Bengali kasa`, - [LangCode.bo]: (i18n) => i18n.str`Tibetan`, - [LangCode.bpy]: (i18n) => i18n.str`Bishnupriya`, - [LangCode.bqi]: (i18n) => i18n.str`Bakhtiari`, - [LangCode.bra]: (i18n) => i18n.str`Braj`, - [LangCode.br]: (i18n) => i18n.str`Breton`, - [LangCode.brh]: (i18n) => i18n.str`Brahui`, - [LangCode.brx]: (i18n) => i18n.str`Bodo`, - [LangCode.bs]: (i18n) => i18n.str`Bosnian`, - [LangCode.bss]: (i18n) => i18n.str`Akoose`, - [LangCode.bua]: (i18n) => i18n.str`Buriat`, - [LangCode.bug]: (i18n) => i18n.str`Buginese`, - [LangCode.bum]: (i18n) => i18n.str`Bulu`, - [LangCode.byn]: (i18n) => i18n.str`Blin`, - [LangCode.byv]: (i18n) => i18n.str`Medumba`, - [LangCode.ca]: (i18n) => i18n.str`Catalan`, - [LangCode.cad]: (i18n) => i18n.str`Caddo`, - [LangCode.car]: (i18n) => i18n.str`Carib`, - [LangCode.cay]: (i18n) => i18n.str`Cayuga`, - [LangCode.cch]: (i18n) => i18n.str`Atsam`, - [LangCode.ceb]: (i18n) => i18n.str`Cebuano`, - [LangCode.ce]: (i18n) => i18n.str`Chechen`, - [LangCode.cgg]: (i18n) => i18n.str`Chiga`, - [LangCode.chb]: (i18n) => i18n.str`Chibcha`, - [LangCode.ch]: (i18n) => i18n.str`Chamorro`, - [LangCode.chg]: (i18n) => i18n.str`Chagatai`, - [LangCode.chk]: (i18n) => i18n.str`Chuukese`, - [LangCode.chm]: (i18n) => i18n.str`Mari`, - [LangCode.chn]: (i18n) => i18n.str`Chinook Jargon`, - [LangCode.cho]: (i18n) => i18n.str`Choctaw`, - [LangCode.chp]: (i18n) => i18n.str`Chipewyan`, - [LangCode.chr]: (i18n) => i18n.str`Cherokee`, - [LangCode.chy]: (i18n) => i18n.str`Cheyenne`, - [LangCode.ckb]: (i18n) => i18n.str`Central Kurdish`, - [LangCode.co]: (i18n) => i18n.str`Corsican`, - [LangCode.cop]: (i18n) => i18n.str`Coptic`, - [LangCode.cps]: (i18n) => i18n.str`Capiznon`, - [LangCode.cr]: (i18n) => i18n.str`Cree`, - [LangCode.crh]: (i18n) => i18n.str`Crimean Turkish`, - [LangCode.csb]: (i18n) => i18n.str`Kashubian`, - [LangCode.cs]: (i18n) => i18n.str`Kyɛk kasa`, - [LangCode.cu]: (i18n) => i18n.str`Church Slavic`, - [LangCode.cv]: (i18n) => i18n.str`Chuvash`, - [LangCode.cy]: (i18n) => i18n.str`Welsh`, - [LangCode.da]: (i18n) => i18n.str`Danish`, - [LangCode.dak]: (i18n) => i18n.str`Dakota`, - [LangCode.dar]: (i18n) => i18n.str`Dargwa`, - [LangCode.dav]: (i18n) => i18n.str`Taita`, - [LangCode.de_AT]: (i18n) => i18n.str`Austrian German`, - [LangCode.de_CH]: (i18n) => i18n.str`Swiss High German`, - [LangCode.de]: (i18n) => i18n.str`Gyaaman`, - [LangCode.del]: (i18n) => i18n.str`Delaware`, - [LangCode.den]: (i18n) => i18n.str`Slave`, - [LangCode.dgr]: (i18n) => i18n.str`Dogrib`, - [LangCode.din]: (i18n) => i18n.str`Dinka`, - [LangCode.dje]: (i18n) => i18n.str`Zarma`, - [LangCode.doi]: (i18n) => i18n.str`Dogri`, - [LangCode.dsb]: (i18n) => i18n.str`Lower Sorbian`, - [LangCode.dtp]: (i18n) => i18n.str`Central Dusun`, - [LangCode.dua]: (i18n) => i18n.str`Duala`, - [LangCode.dum]: (i18n) => i18n.str`Middle Dutch`, - [LangCode.dv]: (i18n) => i18n.str`Divehi`, - [LangCode.dyo]: (i18n) => i18n.str`Jola-Fonyi`, - [LangCode.dyu]: (i18n) => i18n.str`Dyula`, - [LangCode.dz]: (i18n) => i18n.str`Dzongkha`, - [LangCode.dzg]: (i18n) => i18n.str`Dazaga`, - [LangCode.ebu]: (i18n) => i18n.str`Embu`, - [LangCode.ee]: (i18n) => i18n.str`Ewe`, - [LangCode.efi]: (i18n) => i18n.str`Efik`, - [LangCode.egl]: (i18n) => i18n.str`Emilian`, - [LangCode.egy]: (i18n) => i18n.str`Ancient Egyptian`, - [LangCode.eka]: (i18n) => i18n.str`Ekajuk`, - [LangCode.el]: (i18n) => i18n.str`Greek kasa`, - [LangCode.elx]: (i18n) => i18n.str`Elamite`, - [LangCode.en_AU]: (i18n) => i18n.str`Australian English`, - [LangCode.en]: (i18n) => i18n.str`Borɔfo`, - [LangCode.en_CA]: (i18n) => i18n.str`Canadian English`, - [LangCode.en_GB]: (i18n) => i18n.str`British English`, - [LangCode.enm]: (i18n) => i18n.str`Middle English`, - [LangCode.en_US]: (i18n) => i18n.str`American English`, - [LangCode.eo]: (i18n) => i18n.str`Esperanto`, - [LangCode.es_419]: (i18n) => i18n.str`Latin American Spanish`, - [LangCode.es_ES]: (i18n) => i18n.str`European Spanish`, - [LangCode.es_MX]: (i18n) => i18n.str`Mexican Spanish`, - [LangCode.es]: (i18n) => i18n.str`Spain kasa`, - [LangCode.esu]: (i18n) => i18n.str`Central Yupik`, - [LangCode.et]: (i18n) => i18n.str`Estonian`, - [LangCode.eu]: (i18n) => i18n.str`Basque`, - [LangCode.ewo]: (i18n) => i18n.str`Ewondo`, - [LangCode.ext]: (i18n) => i18n.str`Extremaduran`, - [LangCode.fan]: (i18n) => i18n.str`Fang`, - [LangCode.fa]: (i18n) => i18n.str`Pɛɛhyia kasa`, - [LangCode.fat]: (i18n) => i18n.str`Fanti`, - [LangCode.ff]: (i18n) => i18n.str`Fulah`, - [LangCode.fi]: (i18n) => i18n.str`Finnish`, - [LangCode.fil]: (i18n) => i18n.str`Filipino`, - [LangCode.fit]: (i18n) => i18n.str`Tornedalen Finnish`, - [LangCode.fj]: (i18n) => i18n.str`Fijian`, - [LangCode.fo]: (i18n) => i18n.str`Faroese`, - [LangCode.fon]: (i18n) => i18n.str`Fon`, - [LangCode.fr_CA]: (i18n) => i18n.str`Canadian French`, - [LangCode.frc]: (i18n) => i18n.str`Cajun French`, - [LangCode.fr_CH]: (i18n) => i18n.str`Swiss French`, - [LangCode.fr]: (i18n) => i18n.str`Frɛnkye`, - [LangCode.frm]: (i18n) => i18n.str`Middle French`, - [LangCode.fro]: (i18n) => i18n.str`Old French`, - [LangCode.frp]: (i18n) => i18n.str`Arpitan`, - [LangCode.frr]: (i18n) => i18n.str`Northern Frisian`, - [LangCode.frs]: (i18n) => i18n.str`Eastern Frisian`, - [LangCode.fur]: (i18n) => i18n.str`Friulian`, - [LangCode.fy]: (i18n) => i18n.str`Western Frisian`, - [LangCode.gaa]: (i18n) => i18n.str`Ga`, - [LangCode.gag]: (i18n) => i18n.str`Gagauz`, - [LangCode.ga]: (i18n) => i18n.str`Irish`, - [LangCode.gan]: (i18n) => i18n.str`Gan Chinese`, - [LangCode.gay]: (i18n) => i18n.str`Gayo`, - [LangCode.gba]: (i18n) => i18n.str`Gbaya`, - [LangCode.gbz]: (i18n) => i18n.str`Zoroastrian Dari`, - [LangCode.gd]: (i18n) => i18n.str`Scottish Gaelic`, - [LangCode.gez]: (i18n) => i18n.str`Geez`, - [LangCode.gil]: (i18n) => i18n.str`Gilbertese`, - [LangCode.gl]: (i18n) => i18n.str`Galician`, - [LangCode.glk]: (i18n) => i18n.str`Gilaki`, - [LangCode.gmh]: (i18n) => i18n.str`Middle High German`, - [LangCode.gn]: (i18n) => i18n.str`Guarani`, - [LangCode.goh]: (i18n) => i18n.str`Old High German`, - [LangCode.gom]: (i18n) => i18n.str`Goan Konkani`, - [LangCode.gon]: (i18n) => i18n.str`Gondi`, - [LangCode.gor]: (i18n) => i18n.str`Gorontalo`, - [LangCode.got]: (i18n) => i18n.str`Gothic`, - [LangCode.grb]: (i18n) => i18n.str`Grebo`, - [LangCode.grc]: (i18n) => i18n.str`Ancient Greek`, - [LangCode.gsw]: (i18n) => i18n.str`Swiss German`, - [LangCode.guc]: (i18n) => i18n.str`Wayuu`, - [LangCode.gu]: (i18n) => i18n.str`Gujarati`, - [LangCode.gur]: (i18n) => i18n.str`Frafra`, - [LangCode.guz]: (i18n) => i18n.str`Gusii`, - [LangCode.gv]: (i18n) => i18n.str`Manx`, - [LangCode.gwi]: (i18n) => i18n.str`Gwichʼin`, - [LangCode.ha]: (i18n) => i18n.str`Hausa`, - [LangCode.hai]: (i18n) => i18n.str`Haida`, - [LangCode.hak]: (i18n) => i18n.str`Hakka Chinese`, - [LangCode.haw]: (i18n) => i18n.str`Hawaiian`, - [LangCode.he]: (i18n) => i18n.str`Hebrew`, - [LangCode.hif]: (i18n) => i18n.str`Fiji Hindi`, - [LangCode.hi]: (i18n) => i18n.str`Hindi`, - [LangCode.hil]: (i18n) => i18n.str`Hiligaynon`, - [LangCode.hit]: (i18n) => i18n.str`Hittite`, - [LangCode.hmn]: (i18n) => i18n.str`Hmong`, - [LangCode.ho]: (i18n) => i18n.str`Hiri Motu`, - [LangCode.hr]: (i18n) => i18n.str`Croatian`, - [LangCode.hsb]: (i18n) => i18n.str`Upper Sorbian`, - [LangCode.hsn]: (i18n) => i18n.str`Xiang Chinese`, - [LangCode.ht]: (i18n) => i18n.str`Haitian`, - [LangCode.hu]: (i18n) => i18n.str`Hangri kasa`, - [LangCode.hup]: (i18n) => i18n.str`Hupa`, - [LangCode.hy]: (i18n) => i18n.str`Armenian`, - [LangCode.hz]: (i18n) => i18n.str`Herero`, - [LangCode.ia]: (i18n) => i18n.str`Interlingua`, - [LangCode.iba]: (i18n) => i18n.str`Iban`, - [LangCode.ibb]: (i18n) => i18n.str`Ibibio`, - [LangCode.id]: (i18n) => i18n.str`Indonihyia kasa`, - [LangCode.ie]: (i18n) => i18n.str`Interlingue`, - [LangCode.ig]: (i18n) => i18n.str`Igbo`, - [LangCode.ii]: (i18n) => i18n.str`Sichuan Yi`, - [LangCode.ik]: (i18n) => i18n.str`Inupiaq`, - [LangCode.ilo]: (i18n) => i18n.str`Iloko`, - [LangCode.inh]: (i18n) => i18n.str`Ingush`, - [LangCode.io]: (i18n) => i18n.str`Ido`, - [LangCode.is]: (i18n) => i18n.str`Icelandic`, - [LangCode.it]: (i18n) => i18n.str`Italy kasa`, - [LangCode.iu]: (i18n) => i18n.str`Inuktitut`, - [LangCode.izh]: (i18n) => i18n.str`Ingrian`, - [LangCode.ja]: (i18n) => i18n.str`Gyapan kasa`, - [LangCode.jam]: (i18n) => i18n.str`Jamaican Creole English`, - [LangCode.jbo]: (i18n) => i18n.str`Lojban`, - [LangCode.jgo]: (i18n) => i18n.str`Ngomba`, - [LangCode.jmc]: (i18n) => i18n.str`Machame`, - [LangCode.jpr]: (i18n) => i18n.str`Judeo-Persian`, - [LangCode.jrb]: (i18n) => i18n.str`Judeo-Arabic`, - [LangCode.jut]: (i18n) => i18n.str`Jutish`, - [LangCode.jv]: (i18n) => i18n.str`Gyabanis kasa`, - [LangCode.kaa]: (i18n) => i18n.str`Kara-Kalpak`, - [LangCode.kab]: (i18n) => i18n.str`Kabyle`, - [LangCode.kac]: (i18n) => i18n.str`Kachin`, - [LangCode.ka]: (i18n) => i18n.str`Georgian`, - [LangCode.kaj]: (i18n) => i18n.str`Jju`, - [LangCode.kam]: (i18n) => i18n.str`Kamba`, - [LangCode.kaw]: (i18n) => i18n.str`Kawi`, - [LangCode.kbd]: (i18n) => i18n.str`Kabardian`, - [LangCode.kbl]: (i18n) => i18n.str`Kanembu`, - [LangCode.kcg]: (i18n) => i18n.str`Tyap`, - [LangCode.kde]: (i18n) => i18n.str`Makonde`, - [LangCode.kea]: (i18n) => i18n.str`Kabuverdianu`, - [LangCode.ken]: (i18n) => i18n.str`Kenyang`, - [LangCode.kfo]: (i18n) => i18n.str`Koro`, - [LangCode.kg]: (i18n) => i18n.str`Kongo`, - [LangCode.kgp]: (i18n) => i18n.str`Kaingang`, - [LangCode.kha]: (i18n) => i18n.str`Khasi`, - [LangCode.kho]: (i18n) => i18n.str`Khotanese`, - [LangCode.khq]: (i18n) => i18n.str`Koyra Chiini`, - [LangCode.khw]: (i18n) => i18n.str`Khowar`, - [LangCode.ki]: (i18n) => i18n.str`Kikuyu`, - [LangCode.kiu]: (i18n) => i18n.str`Kirmanjki`, - [LangCode.kj]: (i18n) => i18n.str`Kuanyama`, - [LangCode.kkj]: (i18n) => i18n.str`Kako`, - [LangCode.kk]: (i18n) => i18n.str`Kazakh`, - [LangCode.kl]: (i18n) => i18n.str`Kalaallisut`, - [LangCode.kln]: (i18n) => i18n.str`Kalenjin`, - [LangCode.kmb]: (i18n) => i18n.str`Kimbundu`, - [LangCode.km]: (i18n) => i18n.str`Kambodia kasa`, - [LangCode.kn]: (i18n) => i18n.str`Kannada`, - [LangCode.koi]: (i18n) => i18n.str`Komi-Permyak`, - [LangCode.kok]: (i18n) => i18n.str`Konkani`, - [LangCode.ko]: (i18n) => i18n.str`Korea kasa`, - [LangCode.kos]: (i18n) => i18n.str`Kosraean`, - [LangCode.kpe]: (i18n) => i18n.str`Kpelle`, - [LangCode.krc]: (i18n) => i18n.str`Karachay-Balkar`, - [LangCode.kri]: (i18n) => i18n.str`Krio`, - [LangCode.krj]: (i18n) => i18n.str`Kinaray-a`, - [LangCode.kr]: (i18n) => i18n.str`Kanuri`, - [LangCode.krl]: (i18n) => i18n.str`Karelian`, - [LangCode.kru]: (i18n) => i18n.str`Kurukh`, - [LangCode.ksb]: (i18n) => i18n.str`Shambala`, - [LangCode.ksf]: (i18n) => i18n.str`Bafia`, - [LangCode.ksh]: (i18n) => i18n.str`Colognian`, - [LangCode.ks]: (i18n) => i18n.str`Kashmiri`, - [LangCode.ku]: (i18n) => i18n.str`Kurdish`, - [LangCode.kum]: (i18n) => i18n.str`Kumyk`, - [LangCode.kut]: (i18n) => i18n.str`Kutenai`, - [LangCode.kv]: (i18n) => i18n.str`Komi`, - [LangCode.kw]: (i18n) => i18n.str`Cornish`, - [LangCode.ky]: (i18n) => i18n.str`Kyrgyz`, - [LangCode.lad]: (i18n) => i18n.str`Ladino`, - [LangCode.lag]: (i18n) => i18n.str`Langi`, - [LangCode.lah]: (i18n) => i18n.str`Lahnda`, - [LangCode.la]: (i18n) => i18n.str`Latin`, - [LangCode.lam]: (i18n) => i18n.str`Lamba`, - [LangCode.lb]: (i18n) => i18n.str`Luxembourgish`, - [LangCode.lez]: (i18n) => i18n.str`Lezghian`, - [LangCode.lfn]: (i18n) => i18n.str`Lingua Franca Nova`, - [LangCode.lg]: (i18n) => i18n.str`Ganda`, - [LangCode.lij]: (i18n) => i18n.str`Ligurian`, - [LangCode.li]: (i18n) => i18n.str`Limburgish`, - [LangCode.liv]: (i18n) => i18n.str`Livonian`, - [LangCode.lkt]: (i18n) => i18n.str`Lakota`, - [LangCode.lmo]: (i18n) => i18n.str`Lombard`, - [LangCode.ln]: (i18n) => i18n.str`Lingala`, - [LangCode.lo]: (i18n) => i18n.str`Lao`, - [LangCode.lol]: (i18n) => i18n.str`Mongo`, - [LangCode.loz]: (i18n) => i18n.str`Lozi`, - [LangCode.ltg]: (i18n) => i18n.str`Latgalian`, - [LangCode.lt]: (i18n) => i18n.str`Lithuanian`, - [LangCode.lua]: (i18n) => i18n.str`Luba-Lulua`, - [LangCode.lui]: (i18n) => i18n.str`Luiseno`, - [LangCode.lu]: (i18n) => i18n.str`Luba-Katanga`, - [LangCode.lun]: (i18n) => i18n.str`Lunda`, - [LangCode.luo]: (i18n) => i18n.str`Luo`, - [LangCode.lus]: (i18n) => i18n.str`Mizo`, - [LangCode.luy]: (i18n) => i18n.str`Luyia`, - [LangCode.lv]: (i18n) => i18n.str`Latvian`, - [LangCode.lzh]: (i18n) => i18n.str`Literary Chinese`, - [LangCode.lzz]: (i18n) => i18n.str`Laz`, - [LangCode.mad]: (i18n) => i18n.str`Madurese`, - [LangCode.maf]: (i18n) => i18n.str`Mafa`, - [LangCode.mag]: (i18n) => i18n.str`Magahi`, - [LangCode.mai]: (i18n) => i18n.str`Maithili`, - [LangCode.mak]: (i18n) => i18n.str`Makasar`, - [LangCode.man]: (i18n) => i18n.str`Mandingo`, - [LangCode.mas]: (i18n) => i18n.str`Masai`, - [LangCode.mde]: (i18n) => i18n.str`Maba`, - [LangCode.mdf]: (i18n) => i18n.str`Moksha`, - [LangCode.mdr]: (i18n) => i18n.str`Mandar`, - [LangCode.men]: (i18n) => i18n.str`Mende`, - [LangCode.mer]: (i18n) => i18n.str`Meru`, - [LangCode.mfe]: (i18n) => i18n.str`Morisyen`, - [LangCode.mga]: (i18n) => i18n.str`Middle Irish`, - [LangCode.mgh]: (i18n) => i18n.str`Makhuwa-Meetto`, - [LangCode.mg]: (i18n) => i18n.str`Malagasy`, - [LangCode.mgo]: (i18n) => i18n.str`Metaʼ`, - [LangCode.mh]: (i18n) => i18n.str`Marshallese`, - [LangCode.mic]: (i18n) => i18n.str`Micmac`, - [LangCode.mi]: (i18n) => i18n.str`Maori`, - [LangCode.min]: (i18n) => i18n.str`Minangkabau`, - [LangCode.mk]: (i18n) => i18n.str`Macedonian`, - [LangCode.ml]: (i18n) => i18n.str`Malayalam`, - [LangCode.mnc]: (i18n) => i18n.str`Manchu`, - [LangCode.mni]: (i18n) => i18n.str`Manipuri`, - [LangCode.mn]: (i18n) => i18n.str`Mongolian`, - [LangCode.moh]: (i18n) => i18n.str`Mohawk`, - [LangCode.mos]: (i18n) => i18n.str`Mossi`, - [LangCode.mrj]: (i18n) => i18n.str`Western Mari`, - [LangCode.mr]: (i18n) => i18n.str`Marathi`, - [LangCode.ms]: (i18n) => i18n.str`Malay kasa`, - [LangCode.mt]: (i18n) => i18n.str`Maltese`, - [LangCode.mua]: (i18n) => i18n.str`Mundang`, - [LangCode.mul]: (i18n) => i18n.str`Multiple Languages`, - [LangCode.mus]: (i18n) => i18n.str`Creek`, - [LangCode.mwl]: (i18n) => i18n.str`Mirandese`, - [LangCode.mwr]: (i18n) => i18n.str`Marwari`, - [LangCode.mwv]: (i18n) => i18n.str`Mentawai`, - [LangCode.my]: (i18n) => i18n.str`Bɛɛmis kasa`, - [LangCode.mye]: (i18n) => i18n.str`Myene`, - [LangCode.myv]: (i18n) => i18n.str`Erzya`, - [LangCode.mzn]: (i18n) => i18n.str`Mazanderani`, - [LangCode.na]: (i18n) => i18n.str`Nauru`, - [LangCode.nan]: (i18n) => i18n.str`Min Nan Chinese`, - [LangCode.nap]: (i18n) => i18n.str`Neapolitan`, - [LangCode.naq]: (i18n) => i18n.str`Nama`, - [LangCode.nb]: (i18n) => i18n.str`Norwegian Bokmål`, - [LangCode.nd]: (i18n) => i18n.str`North Ndebele`, - [LangCode.nds]: (i18n) => i18n.str`Low German`, - [LangCode.ne]: (i18n) => i18n.str`Nɛpal kasa`, - [LangCode.new]: (i18n) => i18n.str`Newari`, - [LangCode.ng]: (i18n) => i18n.str`Ndonga`, - [LangCode.nia]: (i18n) => i18n.str`Nias`, - [LangCode.niu]: (i18n) => i18n.str`Niuean`, - [LangCode.njo]: (i18n) => i18n.str`Ao Naga`, - [LangCode.nl_BE]: (i18n) => i18n.str`Flemish`, - [LangCode.nl]: (i18n) => i18n.str`Dɛɛkye`, - [LangCode.nmg]: (i18n) => i18n.str`Kwasio`, - [LangCode.nnh]: (i18n) => i18n.str`Ngiemboon`, - [LangCode.nn]: (i18n) => i18n.str`Norwegian Nynorsk`, - [LangCode.nog]: (i18n) => i18n.str`Nogai`, - [LangCode.non]: (i18n) => i18n.str`Old Norse`, - [LangCode.no]: (i18n) => i18n.str`Norwegian`, - [LangCode.nov]: (i18n) => i18n.str`Novial`, - [LangCode.nqo]: (i18n) => i18n.str`NʼKo`, - [LangCode.nr]: (i18n) => i18n.str`South Ndebele`, - [LangCode.nso]: (i18n) => i18n.str`Northern Sotho`, - [LangCode.nus]: (i18n) => i18n.str`Nuer`, - [LangCode.nv]: (i18n) => i18n.str`Navajo`, - [LangCode.nwc]: (i18n) => i18n.str`Classical Newari`, - [LangCode.nym]: (i18n) => i18n.str`Nyamwezi`, - [LangCode.nyn]: (i18n) => i18n.str`Nyankole`, - [LangCode.ny]: (i18n) => i18n.str`Nyanja`, - [LangCode.nyo]: (i18n) => i18n.str`Nyoro`, - [LangCode.nzi]: (i18n) => i18n.str`Nzima`, - [LangCode.oc]: (i18n) => i18n.str`Occitan`, - [LangCode.oj]: (i18n) => i18n.str`Ojibwa`, - [LangCode.om]: (i18n) => i18n.str`Oromo`, - [LangCode.or]: (i18n) => i18n.str`Oriya`, - [LangCode.osa]: (i18n) => i18n.str`Osage`, - [LangCode.os]: (i18n) => i18n.str`Ossetic`, - [LangCode.ota]: (i18n) => i18n.str`Ottoman Turkish`, - [LangCode.pag]: (i18n) => i18n.str`Pangasinan`, - [LangCode.pal]: (i18n) => i18n.str`Pahlavi`, - [LangCode.pam]: (i18n) => i18n.str`Pampanga`, - [LangCode.pap]: (i18n) => i18n.str`Papiamento`, - [LangCode.pa]: (i18n) => i18n.str`Pungyabi kasa`, - [LangCode.pau]: (i18n) => i18n.str`Palauan`, - [LangCode.pcd]: (i18n) => i18n.str`Picard`, - [LangCode.pdc]: (i18n) => i18n.str`Pennsylvania German`, - [LangCode.pdt]: (i18n) => i18n.str`Plautdietsch`, - [LangCode.peo]: (i18n) => i18n.str`Old Persian`, - [LangCode.pfl]: (i18n) => i18n.str`Palatine German`, - [LangCode.phn]: (i18n) => i18n.str`Phoenician`, - [LangCode.pi]: (i18n) => i18n.str`Pali`, - [LangCode.pl]: (i18n) => i18n.str`Pɔland kasa`, - [LangCode.pms]: (i18n) => i18n.str`Piedmontese`, - [LangCode.pnt]: (i18n) => i18n.str`Pontic`, - [LangCode.pon]: (i18n) => i18n.str`Pohnpeian`, - [LangCode.prg]: (i18n) => i18n.str`Prussian`, - [LangCode.pro]: (i18n) => i18n.str`Old Provençal`, - [LangCode.ps]: (i18n) => i18n.str`Pashto`, - [LangCode.pt_BR]: (i18n) => i18n.str`Brazilian Portuguese`, - [LangCode.pt]: (i18n) => i18n.str`Pɔɔtugal kasa`, - [LangCode.pt_PT]: (i18n) => i18n.str`European Portuguese`, - [LangCode.quc]: (i18n) => i18n.str`Kʼicheʼ`, - [LangCode.qug]: (i18n) => i18n.str`Chimborazo Highland Quichua`, - [LangCode.qu]: (i18n) => i18n.str`Quechua`, - [LangCode.raj]: (i18n) => i18n.str`Rajasthani`, - [LangCode.rap]: (i18n) => i18n.str`Rapanui`, - [LangCode.rar]: (i18n) => i18n.str`Rarotongan`, - [LangCode.rgn]: (i18n) => i18n.str`Romagnol`, - [LangCode.rif]: (i18n) => i18n.str`Riffian`, - [LangCode.rm]: (i18n) => i18n.str`Romansh`, - [LangCode.rn]: (i18n) => i18n.str`Rundi`, - [LangCode.rof]: (i18n) => i18n.str`Rombo`, - [LangCode.ro_MD]: (i18n) => i18n.str`Moldavian`, - [LangCode.rom]: (i18n) => i18n.str`Romany`, - [LangCode.root]: (i18n) => i18n.str`Root`, - [LangCode.ro]: (i18n) => i18n.str`Romenia kasa`, - [LangCode.rtm]: (i18n) => i18n.str`Rotuman`, - [LangCode.rue]: (i18n) => i18n.str`Rusyn`, - [LangCode.rug]: (i18n) => i18n.str`Roviana`, - [LangCode.rup]: (i18n) => i18n.str`Aromanian`, - [LangCode.ru]: (i18n) => i18n.str`Rahyia kasa`, - [LangCode.rwk]: (i18n) => i18n.str`Rwa`, - [LangCode.rw]: (i18n) => i18n.str`Rewanda kasa`, - [LangCode.sad]: (i18n) => i18n.str`Sandawe`, - [LangCode.sah]: (i18n) => i18n.str`Sakha`, - [LangCode.sam]: (i18n) => i18n.str`Samaritan Aramaic`, - [LangCode.saq]: (i18n) => i18n.str`Samburu`, - [LangCode.sa]: (i18n) => i18n.str`Sanskrit`, - [LangCode.sas]: (i18n) => i18n.str`Sasak`, - [LangCode.sat]: (i18n) => i18n.str`Santali`, - [LangCode.saz]: (i18n) => i18n.str`Saurashtra`, - [LangCode.sba]: (i18n) => i18n.str`Ngambay`, - [LangCode.sbp]: (i18n) => i18n.str`Sangu`, - [LangCode.scn]: (i18n) => i18n.str`Sicilian`, - [LangCode.sco]: (i18n) => i18n.str`Scots`, - [LangCode.sc]: (i18n) => i18n.str`Sardinian`, - [LangCode.sdc]: (i18n) => i18n.str`Sassarese Sardinian`, - [LangCode.sd]: (i18n) => i18n.str`Sindhi`, - [LangCode.see]: (i18n) => i18n.str`Seneca`, - [LangCode.seh]: (i18n) => i18n.str`Sena`, - [LangCode.sei]: (i18n) => i18n.str`Seri`, - [LangCode.sel]: (i18n) => i18n.str`Selkup`, - [LangCode.se]: (i18n) => i18n.str`Northern Sami`, - [LangCode.ses]: (i18n) => i18n.str`Koyraboro Senni`, - [LangCode.sga]: (i18n) => i18n.str`Old Irish`, - [LangCode.sg]: (i18n) => i18n.str`Sango`, - [LangCode.sgs]: (i18n) => i18n.str`Samogitian`, - [LangCode.shi]: (i18n) => i18n.str`Tachelhit`, - [LangCode.shn]: (i18n) => i18n.str`Shan`, - [LangCode.sh]: (i18n) => i18n.str`Serbo-Croatian`, - [LangCode.shu]: (i18n) => i18n.str`Chadian Arabic`, - [LangCode.sid]: (i18n) => i18n.str`Sidamo`, - [LangCode.si]: (i18n) => i18n.str`Sinhala`, - [LangCode.sk]: (i18n) => i18n.str`Slovak`, - [LangCode.sli]: (i18n) => i18n.str`Lower Silesian`, - [LangCode.sl]: (i18n) => i18n.str`Slovenian`, - [LangCode.sly]: (i18n) => i18n.str`Selayar`, - [LangCode.sma]: (i18n) => i18n.str`Southern Sami`, - [LangCode.smj]: (i18n) => i18n.str`Lule Sami`, - [LangCode.smn]: (i18n) => i18n.str`Inari Sami`, - [LangCode.sm]: (i18n) => i18n.str`Samoan`, - [LangCode.sms]: (i18n) => i18n.str`Skolt Sami`, - [LangCode.snk]: (i18n) => i18n.str`Soninke`, - [LangCode.sn]: (i18n) => i18n.str`Shona`, - [LangCode.sog]: (i18n) => i18n.str`Sogdien`, - [LangCode.so]: (i18n) => i18n.str`Somalia kasa`, - [LangCode.sq]: (i18n) => i18n.str`Albanian`, - [LangCode.srn]: (i18n) => i18n.str`Sranan Tongo`, - [LangCode.srr]: (i18n) => i18n.str`Serer`, - [LangCode.sr]: (i18n) => i18n.str`Serbian`, - [LangCode.ss]: (i18n) => i18n.str`Swati`, - [LangCode.ssy]: (i18n) => i18n.str`Saho`, - [LangCode.stq]: (i18n) => i18n.str`Saterland Frisian`, - [LangCode.st]: (i18n) => i18n.str`Southern Sotho`, - [LangCode.suk]: (i18n) => i18n.str`Sukuma`, - [LangCode.sus]: (i18n) => i18n.str`Susu`, - [LangCode.su]: (i18n) => i18n.str`Sundanese`, - [LangCode.sux]: (i18n) => i18n.str`Sumerian`, - [LangCode.sv]: (i18n) => i18n.str`Sweden kasa`, - [LangCode.swb]: (i18n) => i18n.str`Comorian`, - [LangCode.swc]: (i18n) => i18n.str`Congo Swahili`, - [LangCode.sw]: (i18n) => i18n.str`Swahili`, - [LangCode.syc]: (i18n) => i18n.str`Classical Syriac`, - [LangCode.syr]: (i18n) => i18n.str`Syriac`, - [LangCode.szl]: (i18n) => i18n.str`Silesian`, - [LangCode.ta]: (i18n) => i18n.str`Tamil kasa`, - [LangCode.tcy]: (i18n) => i18n.str`Tulu`, - [LangCode.tem]: (i18n) => i18n.str`Timne`, - [LangCode.teo]: (i18n) => i18n.str`Teso`, - [LangCode.ter]: (i18n) => i18n.str`Tereno`, - [LangCode.te]: (i18n) => i18n.str`Telugu`, - [LangCode.tet]: (i18n) => i18n.str`Tetum`, - [LangCode.tg]: (i18n) => i18n.str`Tajik`, - [LangCode.th]: (i18n) => i18n.str`Taeland kasa`, - [LangCode.tig]: (i18n) => i18n.str`Tigre`, - [LangCode.ti]: (i18n) => i18n.str`Tigrinya`, - [LangCode.tiv]: (i18n) => i18n.str`Tiv`, - [LangCode.tkl]: (i18n) => i18n.str`Tokelau`, - [LangCode.tkr]: (i18n) => i18n.str`Tsakhur`, - [LangCode.tk]: (i18n) => i18n.str`Turkmen`, - [LangCode.tlh]: (i18n) => i18n.str`Klingon`, - [LangCode.tli]: (i18n) => i18n.str`Tlingit`, - [LangCode.tl]: (i18n) => i18n.str`Tagalog`, - [LangCode.tly]: (i18n) => i18n.str`Talysh`, - [LangCode.tmh]: (i18n) => i18n.str`Tamashek`, - [LangCode.tn]: (i18n) => i18n.str`Tswana`, - [LangCode.tog]: (i18n) => i18n.str`Nyasa Tonga`, - [LangCode.to]: (i18n) => i18n.str`Tongan`, - [LangCode.tpi]: (i18n) => i18n.str`Tok Pisin`, - [LangCode.tr]: (i18n) => i18n.str`Tɛɛki kasa`, - [LangCode.tru]: (i18n) => i18n.str`Turoyo`, - [LangCode.trv]: (i18n) => i18n.str`Taroko`, - [LangCode.tsd]: (i18n) => i18n.str`Tsakonian`, - [LangCode.tsi]: (i18n) => i18n.str`Tsimshian`, - [LangCode.ts]: (i18n) => i18n.str`Tsonga`, - [LangCode.tt]: (i18n) => i18n.str`Tatar`, - [LangCode.ttt]: (i18n) => i18n.str`Muslim Tat`, - [LangCode.tum]: (i18n) => i18n.str`Tumbuka`, - [LangCode.tvl]: (i18n) => i18n.str`Tuvalu`, - [LangCode.twq]: (i18n) => i18n.str`Tasawaq`, - [LangCode.tw]: (i18n) => i18n.str`Twi`, - [LangCode.ty]: (i18n) => i18n.str`Tahitian`, - [LangCode.tyv]: (i18n) => i18n.str`Tuvinian`, - [LangCode.tzm]: (i18n) => i18n.str`Central Atlas Tamazight`, - [LangCode.udm]: (i18n) => i18n.str`Udmurt`, - [LangCode.uga]: (i18n) => i18n.str`Ugaritic`, - [LangCode.ug]: (i18n) => i18n.str`Uyghur`, - [LangCode.uk]: (i18n) => i18n.str`Ukren kasa`, - [LangCode.umb]: (i18n) => i18n.str`Umbundu`, - [LangCode.und]: (i18n) => i18n.str`Unknown Language`, - [LangCode.ur]: (i18n) => i18n.str`Urdu kasa`, - [LangCode.uz]: (i18n) => i18n.str`Uzbek`, - [LangCode.vai]: (i18n) => i18n.str`Vai`, - [LangCode.vec]: (i18n) => i18n.str`Venetian`, - [LangCode.vep]: (i18n) => i18n.str`Veps`, - [LangCode.ve]: (i18n) => i18n.str`Venda`, - [LangCode.vi]: (i18n) => i18n.str`Viɛtnam kasa`, - [LangCode.vls]: (i18n) => i18n.str`West Flemish`, - [LangCode.vmf]: (i18n) => i18n.str`Main-Franconian`, - [LangCode.vot]: (i18n) => i18n.str`Votic`, - [LangCode.vo]: (i18n) => i18n.str`Volapük`, - [LangCode.vro]: (i18n) => i18n.str`Võro`, - [LangCode.vun]: (i18n) => i18n.str`Vunjo`, - [LangCode.wae]: (i18n) => i18n.str`Walser`, - [LangCode.wal]: (i18n) => i18n.str`Wolaytta`, - [LangCode.war]: (i18n) => i18n.str`Waray`, - [LangCode.was]: (i18n) => i18n.str`Washo`, - [LangCode.wa]: (i18n) => i18n.str`Walloon`, - [LangCode.wbp]: (i18n) => i18n.str`Warlpiri`, - [LangCode.wo]: (i18n) => i18n.str`Wolof`, - [LangCode.wuu]: (i18n) => i18n.str`Wu Chinese`, - [LangCode.xal]: (i18n) => i18n.str`Kalmyk`, - [LangCode.xh]: (i18n) => i18n.str`Xhosa`, - [LangCode.xmf]: (i18n) => i18n.str`Mingrelian`, - [LangCode.xog]: (i18n) => i18n.str`Soga`, - [LangCode.yao]: (i18n) => i18n.str`Yao`, - [LangCode.yap]: (i18n) => i18n.str`Yapese`, - [LangCode.yav]: (i18n) => i18n.str`Yangben`, - [LangCode.ybb]: (i18n) => i18n.str`Yemba`, - [LangCode.yi]: (i18n) => i18n.str`Yiddish`, - [LangCode.yo]: (i18n) => i18n.str`Yoruba`, - [LangCode.yrl]: (i18n) => i18n.str`Nheengatu`, - [LangCode.yue]: (i18n) => i18n.str`Cantonese`, - [LangCode.zap]: (i18n) => i18n.str`Zapotec`, - [LangCode.za]: (i18n) => i18n.str`Zhuang`, - [LangCode.zbl]: (i18n) => i18n.str`Blissymbols`, - [LangCode.zea]: (i18n) => i18n.str`Zeelandic`, - [LangCode.zen]: (i18n) => i18n.str`Zenaga`, - [LangCode.zgh]: (i18n) => i18n.str`Standard Moroccan Tamazight`, - [LangCode.zh_Hans]: (i18n) => i18n.str`Simplified Chinese`, - [LangCode.zh_Hant]: (i18n) => i18n.str`Traditional Chinese`, - [LangCode.zh]: (i18n) => i18n.str`Kyaena kasa`, - [LangCode.zun]: (i18n) => i18n.str`Zuni`, - [LangCode.zu]: (i18n) => i18n.str`Zulu`, - [LangCode.zxx]: (i18n) => i18n.str`No linguistic content`, - [LangCode.zza]: (i18n) => i18n.str`Zaza`, -}; diff --git a/packages/taler-util/src/kdf.ts b/packages/taler-util/src/kdf.ts @@ -20,36 +20,6 @@ export function sha512(data: Uint8Array): Uint8Array { return platformCrypto.hashSha512(data); } -export function hmac( - digest: (d: Uint8Array) => Uint8Array, - blockSize: number, - key: Uint8Array, - message: Uint8Array, -): Uint8Array { - if (key.byteLength > blockSize) { - key = digest(key); - } - if (key.byteLength < blockSize) { - const k = key; - key = new Uint8Array(blockSize); - key.set(k, 0); - } - const okp = new Uint8Array(blockSize); - const ikp = new Uint8Array(blockSize); - for (let i = 0; i < blockSize; i++) { - ikp[i] = key[i] ^ 0x36; - okp[i] = key[i] ^ 0x5c; - } - const b1 = new Uint8Array(blockSize + message.byteLength); - b1.set(ikp, 0); - b1.set(message, blockSize); - const h0 = digest(b1); - const b2 = new Uint8Array(blockSize + h0.length); - b2.set(okp, 0); - b2.set(h0, blockSize); - return digest(b2); -} - export function hmacSha512(key: Uint8Array, message: Uint8Array): Uint8Array { return platformCrypto.hmacSha512(key, message); } diff --git a/packages/taler-util/src/kyc-aml-utils.ts b/packages/taler-util/src/kyc-aml-utils.ts @@ -1,63 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022-2024 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 { AmlProgramParams, KycConverterParams } from "./types-taler-kyc-aml.js"; - -// https://docs.taler.net/taler-kyc-manual.html#implementing-your-own-aml-programs - -export function parseKycConverterParams(): KycConverterParams { - return process.argv.reduce((prev, arg, idx, list) => { - if (idx === 0) { - prev.name = arg; - } - if (arg === "-v") { - prev.showVersion = true; - } else if (arg === "-V") { - prev.debug = true; - } else if (arg === "--list-outputs") { - prev.showOutputs = true; - } else if (arg === "-h") { - prev.showHelp = true; - } else if (arg === "-c") { - prev.config = list[idx + 1]; - } - return prev; - }, {} as KycConverterParams); -} - -export function parseAmlProgramParams(): AmlProgramParams { - return process.argv.reduce((prev, arg, idx, list) => { - if (idx === 0) { - prev.name = arg; - } - if (arg === "-v") { - prev.showVersion = true; - } else if (arg === "-V") { - prev.debug = true; - } else if (arg === "-r") { - prev.showRequiredContext = true; - } else if (arg === "-a") { - prev.showRequiredAttributes = true; - } else if (arg === "-i") { - prev.showRequiredInputs = true; - } else if (arg === "-h") { - prev.showHelp = true; - } else if (arg === "-c") { - prev.config = list[idx + 1]; - } - return prev; - }, {} as AmlProgramParams); -} diff --git a/packages/taler-util/src/logging.ts b/packages/taler-util/src/logging.ts @@ -65,10 +65,6 @@ export function setGlobalLogLevelFromString(logLevelStr: string): void { globalLogLevel = getLevelForString(logLevelStr); } -export function setLogLevelFromString(tag: string, logLevelStr: string): void { - byTagLogLevel[tag] = getLevelForString(logLevelStr); -} - export function enableNativeLogging() { nativeLogging = true; } diff --git a/packages/taler-util/src/operation.ts b/packages/taler-util/src/operation.ts @@ -269,10 +269,6 @@ export function opKnownTalerFailure<T extends TalerErrorCode>( return { type: "fail", response: resp, case: _case, detail }; } -export function opUnknownFailure(error: unknown): never { - throw TalerError.fromException(error); -} - /** * The operation result should be ok * Return the body of the result @@ -314,36 +310,6 @@ export function throwUnexpectedResponse( } /** - * The operation is expected to fail. - * Return the error details. - * Throw if the operation didn't fail with expected code. - * - * @param resp - * @param s - * @returns - */ -export function failOrThrow<E>( - resp: OperationResult<unknown, E>, - s: E, -): TalerErrorDetail | undefined { - if (isOperationOk(resp)) { - throw TalerError.fromException( - new Error(`request succeed but failure "${s}" was expected`), - ); - } - if (isOperationFail(resp) && resp.case === s) { - return resp.detail; - } - throw TalerError.fromException( - new Error( - `request failed with "${JSON.stringify( - resp, - )}" but case "${s}" was expected`, - ), - ); -} - -/** * The operation is expected to fail with a body. * Return the body of the result. * Throw if the operation didn't fail with expected code. diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts @@ -971,9 +971,7 @@ export namespace Paytos { return uri.fullPath; } - export function getBic( - uri: URI | undefined | null, - ): string | undefined { + export function getBic(uri: URI | undefined | null): string | undefined { if (!uri) return undefined; if (uri.targetType === PaytoType.IBAN) { return uri.bic || uri.params["bic"]; @@ -981,9 +979,7 @@ export namespace Paytos { return uri.params["bic"]; } - export function getBankHost( - uri: URI | undefined | null, - ): string | undefined { + export function getBankHost(uri: URI | undefined | null): string | undefined { if (!uri) return undefined; if (uri.targetType === PaytoType.TalerBank) { return uri.host; @@ -991,9 +987,7 @@ export namespace Paytos { return undefined; } - export function getTargetLabel( - uri: URI | undefined | null, - ): string { + export function getTargetLabel(uri: URI | undefined | null): string { if (!uri) return "Payout Account"; if (uri.targetType === PaytoType.IBAN) return "IBAN"; if (uri.targetType === PaytoType.TalerBank) return "Taler Bank"; @@ -1020,15 +1014,24 @@ export namespace Paytos { export function constructPayto(fields: PaytoInputFields): string { const holder = fields.accountHolder?.trim(); - const search: Record<string, string> = holder ? { "receiver-name": holder } : {}; + const search: Record<string, string> = holder + ? { "receiver-name": holder } + : {}; if (fields.targetType === PaytoType.IBAN || fields.targetType === "iban") { - const cleanIban = (fields.iban || "").replace(/\s+/g, "").toUpperCase() as IbanString; + const cleanIban = (fields.iban || "") + .replace(/\s+/g, "") + .toUpperCase() as IbanString; return toFullString(createIban(cleanIban, undefined, search)); } - if (fields.targetType === PaytoType.TalerBank || fields.targetType === "x-taler-bank") { - const hostStr = (fields.bankHost || "").trim().replace(/^https?:\/\//, ""); + if ( + fields.targetType === PaytoType.TalerBank || + fields.targetType === "x-taler-bank" + ) { + const hostStr = (fields.bankHost || "") + .trim() + .replace(/^https?:\/\//, ""); const host = parseHostPortPath2(hostStr, "") || (hostStr as HostPortPath); const acc = (fields.accountName || "").trim(); return toFullString(createTalerBank(host, acc, search)); @@ -1074,25 +1077,6 @@ export function codecFullForPaytoString(): Codec<Paytos.FullPaytoString> { }; } -export function codecNormalizedForPaytoString(): Codec<Paytos.NormalizedPaytoString> { - return { - decode(x: any, c?: Context): Paytos.NormalizedPaytoString { - // TODO: implement a stronger validation and reject invalid paytos - if (typeof x !== "string") { - throw new DecodingError( - `expected string at ${renderContext(c)} but got ${typeof x}`, - ); - } - if (!x.startsWith(PAYTO_PREFIX)) { - throw new DecodingError( - `expected start with payto at ${renderContext(c)} but got "${x}"`, - ); - } - return x as Paytos.NormalizedPaytoString; - }, - }; -} - /** * @deprecated use codecForNormalizedPAyto or codecForFullPayto * @returns diff --git a/packages/taler-util/src/sha256.ts b/packages/taler-util/src/sha256.ts @@ -271,90 +271,6 @@ export class HashSha256 { } // HMAC implements HMAC-SHA256 message authentication algorithm. -export class HMAC { - private inner: HashSha256 = new HashSha256(); - private outer: HashSha256 = new HashSha256(); - - blockSize: number = this.inner.blockSize; - digestLength: number = this.inner.digestLength; - - // Copies of hash states after keying. - // Need for quick reset without hashing they key again. - private istate: Uint32Array; - private ostate: Uint32Array; - - constructor(key: Uint8Array) { - const pad = new Uint8Array(this.blockSize); - if (key.length > this.blockSize) { - new HashSha256().update(key).finish(pad).clean(); - } else { - for (let i = 0; i < key.length; i++) { - pad[i] = key[i]; - } - } - for (let i = 0; i < pad.length; i++) { - pad[i] ^= 0x36; - } - this.inner.update(pad); - - for (let i = 0; i < pad.length; i++) { - pad[i] ^= 0x36 ^ 0x5c; - } - this.outer.update(pad); - - this.istate = new Uint32Array(8); - this.ostate = new Uint32Array(8); - - this.inner._saveState(this.istate); - this.outer._saveState(this.ostate); - - for (let i = 0; i < pad.length; i++) { - pad[i] = 0; - } - } - - // Returns HMAC state to the state initialized with key - // to make it possible to run HMAC over the other data with the same - // key without creating a new instance. - reset(): this { - this.inner._restoreState(this.istate, this.inner.blockSize); - this.outer._restoreState(this.ostate, this.outer.blockSize); - return this; - } - - // Cleans HMAC state. - clean(): void { - for (let i = 0; i < this.istate.length; i++) { - this.ostate[i] = this.istate[i] = 0; - } - this.inner.clean(); - this.outer.clean(); - } - - // Updates state with provided data. - update(data: Uint8Array): this { - this.inner.update(data); - return this; - } - - // Finalizes HMAC and puts the result in out. - finish(out: Uint8Array): this { - if (this.outer.finished) { - this.outer.finish(out); - } else { - this.inner.finish(out); - this.outer.update(out, this.digestLength).finish(out); - } - return this; - } - - // Returns message authentication code. - digest(): Uint8Array { - const out = new Uint8Array(this.digestLength); - this.finish(out); - return out; - } -} // Returns SHA256 hash of data. export function sha256(data: Uint8Array): Uint8Array { @@ -365,9 +281,3 @@ export function sha256(data: Uint8Array): Uint8Array { } // Returns HMAC-SHA256 of data under the key. -export function hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array { - const h = new HMAC(key).update(data); - const digest = h.digest(); - h.clean(); - return digest; -} diff --git a/packages/taler-util/src/taler-crypto.ts b/packages/taler-util/src/taler-crypto.ts @@ -841,18 +841,6 @@ export function deriveCsCoinPriv( } /** - * Derive a Clause-Schnorr withdrawal nonce. - * Note: In withdraw protocol, the nonce is chosen randomly - * @param coinPriv coin private key - * @returns nonce - */ -export function deriveWithdrawNonce(coinPriv: Uint8Array): Uint8Array { - const outLen = 32; - const salt = stringToBytes("n"); - return kdf(outLen, coinPriv, salt); -} - -/** * Derive a unique blinding master seed for a one-coin withdrawal request. * Keeping CS withdrawals one coin per request makes retries independent and * avoids ever reusing a Clause-Schnorr nonce across partially completed @@ -982,11 +970,6 @@ export interface EcdheKeyPair { ecdhePriv: Uint8Array; } -export interface Edx25519Keypair { - edxPub: string; - edxPriv: string; -} - export function createEddsaKeyPair(): EddsaKeyPair { const eddsaPriv = randomBytes(32); const eddsaPub = eddsaGetPublic(eddsaPriv); @@ -1183,14 +1166,6 @@ export function createHashContext(): TalerHashState { return platformCrypto.createSha512Context(); } -export interface FreshCoin { - coinPub: Uint8Array; - coinPriv: Uint8Array; - bks: Uint8Array; - maxAge: number; - ageCommitmentProof: AgeCommitmentProof | undefined; -} - export function bufferForUint16(n: number): Uint8Array { const arrBuf = new ArrayBuffer(2); const buf = new Uint8Array(arrBuf); @@ -1222,43 +1197,6 @@ export function bufferForUint64(n: number): Uint8Array { return buf; } -export function bufferForUint8(n: number): Uint8Array { - const arrBuf = new ArrayBuffer(1); - const buf = new Uint8Array(arrBuf); - const dv = new DataView(arrBuf); - dv.setUint8(0, n); - return buf; -} - -export async function setupTipPlanchet( - secretSeed: Uint8Array, - denomPub: DenominationPubKey, - coinNumber: number, -): Promise<FreshCoin> { - const info = stringToBytes("taler-tip-coin-derivation"); - const saltArrBuf = new ArrayBuffer(4); - const salt = new Uint8Array(saltArrBuf); - const saltDataView = new DataView(saltArrBuf); - saltDataView.setUint32(0, coinNumber); - const out = kdf(64, secretSeed, salt, info); - const coinPriv = out.slice(0, 32); - const bks = out.slice(32, 64); - let maybeAcp: AgeCommitmentProof | undefined; - if (denomPub.age_mask != 0) { - maybeAcp = await AgeRestriction.restrictionCommitSeeded( - denomPub.age_mask, - AgeRestriction.AGE_UNRESTRICTED, - secretSeed, - ); - } - return { - bks, - coinPriv, - coinPub: eddsaGetPublic(coinPriv), - maxAge: AgeRestriction.AGE_UNRESTRICTED, - ageCommitmentProof: maybeAcp, - }; -} /** * * @param paytoUri diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts @@ -499,7 +499,10 @@ export namespace Duration { if ("d_us" in duration) { us = duration.d_us; } else if ("d_ms" in duration) { - us = duration.d_ms === "forever" ? "forever" : Math.round(duration.d_ms * 1000); + us = + duration.d_ms === "forever" + ? "forever" + : Math.round(duration.d_ms * 1000); } else { return undefined; } @@ -530,7 +533,10 @@ export namespace Duration { if ("d_us" in duration) { us = duration.d_us; } else if ("d_ms" in duration) { - us = duration.d_ms === "forever" ? "forever" : Math.round(duration.d_ms * 1000); + us = + duration.d_ms === "forever" + ? "forever" + : Math.round(duration.d_ms * 1000); } else { return undefined; } @@ -806,7 +812,8 @@ export namespace AbsoluteTime { ): number | undefined { if (!val) return undefined; if (typeof val === "number") return val > 1e11 ? val : val * 1000; - if (val instanceof Date) return isNaN(val.getTime()) ? undefined : val.getTime(); + if (val instanceof Date) + return isNaN(val.getTime()) ? undefined : val.getTime(); if (typeof val === "string") { if (val === "never") return undefined; const parsed = Date.parse(val); @@ -929,7 +936,10 @@ export namespace AbsoluteTime { options?: FormatDateOptions, ): string { if (!val) return fallback; - if (val === "never" || (typeof val === "object" && "t_s" in val && val.t_s === "never")) { + if ( + val === "never" || + (typeof val === "object" && "t_s" in val && val.t_s === "never") + ) { return "Never"; } const ms = parseTimestampMs(val); @@ -975,13 +985,6 @@ export function durationMul(d: Duration, n: number): Duration { return { d_ms: Math.round(d.d_ms * n) }; } -export function durationAdd(d1: Duration, d2: Duration): Duration { - if (d1.d_ms === "forever" || d2.d_ms === "forever") { - return { d_ms: "forever" }; - } - return { d_ms: d1.d_ms + d2.d_ms }; -} - /** * The protocol specification declares every timestamp and duration as an * Integer, capped at 2^53 - 1. Values outside that -- NaN in particular, diff --git a/packages/taler-util/src/types-donau.ts b/packages/taler-util/src/types-donau.ts @@ -29,7 +29,7 @@ import { codecForString, codecOptional, } from "./codec.js"; -import { codecForTimestamp, TalerProtocolTimestamp } from "./time.js"; +import { TalerProtocolTimestamp } from "./time.js"; import { EddsaPublicKeyString, BlindedRsaSignature, @@ -86,15 +86,6 @@ export class DonauSignKeyJson { master_sig: EddsaSignatureString; } -export const codecForDonauSignKeyJson = (): Codec<DonauSignKeyJson> => - buildCodecForObject<DonauSignKeyJson>() - .property("key", codecForEddsaPublicKey()) - .property("master_sig", codecForEddsaSignature()) - .property("stamp_end", codecForTimestamp) - .property("stamp_start", codecForTimestamp) - .property("stamp_expire", codecForTimestamp) - .build("DonauSignKeyJson"); - export interface DonauKeysResponse { // libtool-style representation of the Donau protocol version, see // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning @@ -166,10 +157,6 @@ export type DonationUnitKeyGroupRsa = DonationUnitKeyGroupCommon & { donation_unit_pub: DonationUnitPubRsa; }; -export type DonationUnitKeyGroupCs = DonationUnitKeyGroupCommon & { - donation_unit_pub: DonationUnitPubCs; -}; - /** * Hash of a donation unit public key, as the donau computes it: the hash of * the encoded key, which is what the wire format carries. diff --git a/packages/taler-util/src/types-taler-bank-integration.ts b/packages/taler-util/src/types-taler-bank-integration.ts @@ -30,11 +30,8 @@ import { import { PaytoString, codecForPaytoString } from "./payto.js"; import { AmountString, - CurrencySpecification, codecForBaseUrlString, codecForCurrencyName, - codecForCurrencySpecificiation, - codecForLibtoolVersion, codecForURLString, } from "./types-taler-common.js"; @@ -44,22 +41,6 @@ export type WithdrawalOperationStatusFlag = | "aborted" | "confirmed"; -export interface BankVersion { - // 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". - version: string; - - // Currency used by this bank. - currency: string; - - // How the bank SPA should render this currency. - currency_specification?: CurrencySpecification; - - // Name of the API. - name: "taler-bank-integration"; -} - export interface BankWithdrawalOperationStatus { // Current status of the operation // pending: the operation is pending parameters selection (exchange and reserve public key) @@ -173,14 +154,6 @@ export interface BankWithdrawalOperationPostResponse { confirm_transfer_url?: string; } -export const codecForBankVersion = (): Codec<BankVersion> => - buildCodecForObject<BankVersion>() - .property("currency", codecForCurrencyName()) - .property("currency_specification", codecOptional(codecForCurrencySpecificiation())) - .property("name", codecForConstString("taler-bank-integration")) - .property("version", codecForLibtoolVersion()) - .build("TalerBankIntegrationApi.BankVersion"); - export const codecForBankWithdrawalOperationStatus = (): Codec<BankWithdrawalOperationStatus> => buildCodecForObject<BankWithdrawalOperationStatus>() diff --git a/packages/taler-util/src/types-taler-common.ts b/packages/taler-util/src/types-taler-common.ts @@ -34,7 +34,6 @@ import { buildCodecForObject, codecForAny, codecForBoolean, - codecForConstString, codecForList, codecForMap, codecForNumber, @@ -58,15 +57,10 @@ export type AmlOfficerPublicKeyP = string; // 32-byte hash code. export type ShortHashCode = string; -export type SHA256HashCode = ShortHashCode; - -export type SHA512HashCode = HashCode; - // 32-byte nonce value, must only be used once. export type CSNonce = string; // 32-byte nonce value, must only be used once. -export type RefreshMasterSeed = string; // 32-byte value representing a scalar multiplier // for scalar operations on points on Curve25519. @@ -87,7 +81,6 @@ export type EddsaPublicKey = EddsaPublicKeyString; // EdDSA and ECDHE public keys always point on Curve25519 // and represented using the standard 256 bits Ed25519 compact format, // converted to Crockford Base32. -export type EddsaPrivateKey = EddsaPrivateKeyString; // EdDSA signatures are transmitted as 64-bytes base32 // binary-encoded objects with just the R and S values (base32_ binary-only). @@ -106,7 +99,6 @@ export type EddsaSignature = EddsaSignatureString; // EdDSA and ECDHE public keys always point on Curve25519 // and represented using the standard 256 bits Ed25519 compact format, // converted to Crockford Base32. -export type EcdhePublicKey = string; // Point on Curve25519 represented using the standard 256 bits Ed25519 compact format, // converted to Crockford Base32. @@ -115,7 +107,6 @@ export type CsRPublic = string; // EdDSA and ECDHE public keys always point on Curve25519 // and represented using the standard 256 bits Ed25519 compact format, // converted to Crockford Base32. -export type EcdhePrivateKey = string; export type CoinPublicKey = EddsaPublicKey; @@ -168,7 +159,6 @@ export interface InternationalizedString { } export type RsaPublicKeyString = string; -export type AgeMask = number; // The string must be a data URL according to RFC 2397 // with explicit mediatype and base64 parameters. @@ -215,7 +205,6 @@ export const codecForURLString = codecForHttpUrlString; */ export const codecForBaseUrlString = codecForCanonicalBaseUrlString; // FIXME: implement this codec -export const codecForLibtoolVersion = codecForString; // FIXME: implement this codec export const codecForCurrencyName = codecForString; // FIXME: implement this codec @@ -268,90 +257,12 @@ export enum ExchangeProtocolVersion { V12 = 12, } -export enum MerchantProtocolVersion { - /** - * Current version supported by the wallet. - */ - V3 = 3, -} - export type HashCodeString = string; export type WireSalt = string; export type Integer = number; -export interface BankConversionInfoConfig { - // 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". - version: string; - - // Name of the API. - name: "taler-conversion-info"; - - regional_currency: string; - - fiat_currency: string; - - // Currency used by this bank. - regional_currency_specification: CurrencySpecification; - - // External currency used during conversion. - fiat_currency_specification: CurrencySpecification; -} - -export const codecForBankConversionInfoConfig = - (): Codec<BankConversionInfoConfig> => - buildCodecForObject<BankConversionInfoConfig>() - .property("name", codecForConstString("taler-conversion-info")) - .property("version", codecForString()) - .property("fiat_currency", codecForString()) - .property("regional_currency", codecForString()) - .property("fiat_currency_specification", codecForCurrencySpecificiation()) - .property( - "regional_currency_specification", - codecForCurrencySpecificiation(), - ) - .build("BankConversionInfoConfig"); - -export interface DenominationExpiredMessage { - // Taler error code. Note that beyond - // expiration this message format is also - // used if the key is not yet valid, or - // has been revoked. - code: number; - - // Signature by the exchange over a - // TALER_DenominationExpiredAffirmationPS. - // Must have purpose TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED. - exchange_sig: EddsaSignatureString; - - // Public key of the exchange used to create - // the 'exchange_sig. - exchange_pub: EddsaPublicKeyString; - - // Hash of the denomination public key that is unknown. - h_denom_pub: HashCodeString; - - // When was the signature created. - timestamp: TalerProtocolTimestamp; - - // What kind of operation was requested that now - // failed? - oper: string; -} - -export const codecForDenominationExpiredMessage = (): Codec<DenominationExpiredMessage> => - buildCodecForObject<DenominationExpiredMessage>() - .property("code", codecForNumber()) - .property("exchange_sig", codecForEddsaSignature()) - .property("exchange_pub", codecForEddsaPublicKey()) - .property("h_denom_pub", codecForString()) - .property("timestamp", codecForTimestamp) - .property("oper", codecForString()) - .build("DenominationExpiredMessage"); - export interface CoinHistoryResponse { // Current balance of the coin. balance: AmountString; @@ -572,11 +483,6 @@ export function createClientSecretAccessToken( return clientSecret as AccessToken; } -export type UserAndPassword = { - username: string; - password: string; -}; - export type UserAndToken = { username: string; token: AccessToken; @@ -637,8 +543,3 @@ export type LongPollParams = { timeoutMs?: number; ct?: CancellationToken; }; - -export interface LoginToken { - token: AccessToken; - expiration: Timestamp; -} diff --git a/packages/taler-util/src/types-taler-corebank.ts b/packages/taler-util/src/types-taler-corebank.ts @@ -405,10 +405,6 @@ export interface ListBankAccountsResponse { accounts: AccountMinimalData[]; } -export interface GetBankAccountByIdResponse { - account: AccountMinimalData; -} - export interface Balance { amount: AmountString; credit_debit_indicator: "credit" | "debit"; @@ -512,35 +508,6 @@ export interface ConversionRateClasses { classes: ConversionRateClass[]; } -export interface AccountConversionRateClass { - // Class unique ID - conversion_rate_class_id: Integer; - - // Minimum fiat amount authorised for cashin before conversion - cashin_min_amount?: AmountString; - - // Exchange rate to buy regional currency from fiat - cashin_ratio?: DecimalNumber; - - // Regional amount fee to subtract after applying the cashin ratio. - cashin_fee?: AmountString; - - // Rounding mode used during cashin conversion - cashin_rounding_mode?: RoundingMode; - - // Minimum regional amount authorised for cashout before conversion - cashout_min_amount?: AmountString; - - // Exchange rate to sell regional currency for fiat - cashout_ratio?: DecimalNumber; - - // Fiat amount fee to subtract after applying the cashout ratio. - cashout_fee?: AmountString; - - // Rounding mode used during cashout conversion - cashout_rounding_mode?: RoundingMode; -} - export interface ConversionRateClassInput { // The name of this class name: string; @@ -675,14 +642,6 @@ export interface CashoutResponse { cashout_id: number; } -/** - * @deprecated since 4, use 2fa - */ -export interface CashoutConfirmRequest { - // the TAN that confirms $CASHOUT_ID. - tan: string; -} - export interface Cashouts { // Every string represents a cash-out operation ID. cashouts: CashoutInfo[]; @@ -715,20 +674,6 @@ export interface CashoutStatusResponse { creation_time: Timestamp; } -export interface ConversionRatesResponse { - // Exchange rate to buy the local currency from the external one - buy_at_ratio: DecimalNumber; - - // Exchange rate to sell the local currency for the external one - sell_at_ratio: DecimalNumber; - - // Fee to subtract after applying the buy ratio. - buy_in_fee: DecimalNumber; - - // Fee to subtract after applying the sell ratio. - sell_out_fee: DecimalNumber; -} - export enum MonitorTimeframeParam { hour, day, @@ -1097,15 +1042,6 @@ export const codecForCashoutStatusResponse = (): Codec<CashoutStatusResponse> => .property("creation_time", codecForTimestamp) .build("TalerCorebankApi.CashoutStatusResponse"); -export const codecForConversionRatesResponse = - (): Codec<ConversionRatesResponse> => - buildCodecForObject<ConversionRatesResponse>() - .property("buy_at_ratio", codecForDecimalNumber()) - .property("buy_in_fee", codecForDecimalNumber()) - .property("sell_at_ratio", codecForDecimalNumber()) - .property("sell_out_fee", codecForDecimalNumber()) - .build("TalerCorebankApi.ConversionRatesResponse"); - export const codecForMonitorResponse = (): Codec<MonitorResponse> => buildCodecForUnion<MonitorResponse>() .discriminateOn("type") diff --git a/packages/taler-util/src/types-taler-directory.ts b/packages/taler-util/src/types-taler-directory.ts @@ -21,21 +21,16 @@ import { Codec, buildCodecForObject, codecForList, - codecForNumber, } from "./codec.js"; import { codecForConstString, codecForString } from "./codec.js"; import { codecForDuration } from "./time.js"; -import { - AmountString, - RelativeTime, -} from "./types-taler-common.js"; +import { AmountString, RelativeTime } from "./types-taler-common.js"; -export const codecForTaldirAliasType = - (): Codec<TaldirAliasType> => - buildCodecForObject<TaldirAliasType>() - .property("name", codecForString()) - .property("challenge_fee", codecForAmountString()) - .build("TalerDirectoryApi.TaldirAliasType"); +export const codecForTaldirAliasType = (): Codec<TaldirAliasType> => + buildCodecForObject<TaldirAliasType>() + .property("name", codecForString()) + .property("challenge_fee", codecForAmountString()) + .build("TalerDirectoryApi.TaldirAliasType"); export const codecForTalerDirectoryConfigResponse = (): Codec<TalerDirectoryConfigResponse> => @@ -52,7 +47,6 @@ interface TaldirAliasType { // per challenge fee challenge_fee: AmountString; - } export interface TalerDirectoryConfigResponse { @@ -72,25 +66,10 @@ export interface TalerDirectoryConfigResponse { } export interface TaldirMailboxDetailResponse { - // Target URI to associate with this alias. target_uri: string; - } -export const codecForTaldirMailboxDetailResponse = (): Codec<TaldirMailboxDetailResponse> => - buildCodecForObject<TaldirMailboxDetailResponse>() - .property("target_uri", codecForString()) - .build("TalerDirectoryApi.TaldirMailboxDetailResponse"); - -export const codecForTalerDirectoryRateLimitedResponse = - (): Codec<TaldirRateLimitedResponse> => - buildCodecForObject<TaldirRateLimitedResponse>() - .property("code", codecForNumber()) - .property("retry_delay", codecForDuration) - .property("hint", codecForString()) - .build("TalerDirectoryApi.TaldirRateLimitedResponse"); - export interface TaldirAlreadyPaidResponse { // The remaining duration for which this registration is still paid for valid_for: RelativeTime; @@ -101,14 +80,3 @@ export const codecForTaldirAlreadyPaidResponse = buildCodecForObject<TaldirAlreadyPaidResponse>() .property("valid_for", codecForDuration) .build("TalerDirectoryApi.TaldirAlreadyPaidResponse"); - -export interface TaldirRateLimitedResponse { - // Taler error code, TALER_EC_TALDIR_DELIVERY_RATE_LIMITED. - code: number; - - // When the client should retry. - retry_delay: RelativeTime; - - // The human readable error message. - hint: string; -} diff --git a/packages/taler-util/src/types-taler-exchange.ts b/packages/taler-util/src/types-taler-exchange.ts @@ -130,27 +130,6 @@ export namespace DenominationPubKey { } } -export const codecForRsaDenominationPubKey = (): Codec<RsaDenominationPubKey> => - buildCodecForObject<RsaDenominationPubKey>() - .property("cipher", codecForConstString(DenomKeyType.Rsa)) - .property("rsa_public_key", codecForString()) - .property("age_mask", codecForNumber()) - .build("DenominationPubKey"); - -export const codecForCsDenominationPubKey = (): Codec<CsDenominationPubKey> => - buildCodecForObject<CsDenominationPubKey>() - .property("cipher", codecForConstString(DenomKeyType.ClauseSchnorr)) - .property("cs_public_key", codecForString()) - .property("age_mask", codecForNumber()) - .build("CsDenominationPubKey"); - -export const codecForDenominationPubKey = (): Codec<DenominationPubKey> => - buildCodecForUnion<DenominationPubKey>() - .discriminateOn("cipher") - .alternative(DenomKeyType.Rsa, codecForRsaDenominationPubKey()) - .alternative(DenomKeyType.ClauseSchnorr, codecForCsDenominationPubKey()) - .build("DenominationPubKey"); - /** * Signature by the auditor that a particular denomination key is audited. */ @@ -538,16 +517,6 @@ export interface ExchangeKeysResponse { kyc_swap_tos_acceptance?: boolean; } -export interface ExchangeMeltRequest { - coin_pub: CoinPublicKeyString; - confirm_sig: EddsaSignatureString; - denom_pub_hash: HashCodeString; - denom_sig: UnblindedDenominationSignature; - rc: string; - value_with_fee: AmountString; - age_commitment_hash?: HashCodeString; -} - /** * Docs name: NewMeltRequest */ @@ -645,15 +614,6 @@ export interface ExchangeMeltResponse { refresh_base_url?: string; } -export interface ExchangeRevealItem { - ev_sig: BlindedDenominationSignature; -} - -export interface ExchangeRevealResponse { - // List of the exchange's blinded RSA signatures on the new coins. - ev_sigs: ExchangeRevealItem[]; -} - export const codecForAuditorDenomSig = (): Codec<AuditorDenomSig> => buildCodecForObject<AuditorDenomSig>() .property("denom_pub_h", codecForString()) @@ -929,30 +889,6 @@ export interface RegexAccountRestriction { human_hint_i18n?: InternationalizedString; } -const codecForDenyAllAccountRestriction = - (): Codec<DenyAllAccountRestriction> => - buildCodecForObject<DenyAllAccountRestriction>() - .property("type", codecForConstString("deny")) - .build("DenyAllAccountRestriction"); - -const codecForRegexAccountRestriction = (): Codec<RegexAccountRestriction> => - buildCodecForObject<RegexAccountRestriction>() - .property("type", codecForConstString("regex")) - .property("payto_regex", codecForString()) - .property("human_hint", codecForString()) - .property( - "human_hint_i18n", - codecOptional(codecForInternationalizedString()), - ) - .build("RegexAccountRestriction"); - -export const codecForAccountRestriction = (): Codec<AccountRestriction> => - buildCodecForUnion<AccountRestriction>() - .discriminateOn("type") - .alternative("deny", codecForDenyAllAccountRestriction()) - .alternative("regex", codecForRegexAccountRestriction()) - .build("AccountRestriction"); - export type CoinEnvelope = CoinEnvelopeRsa | CoinEnvelopeCs; export interface CoinEnvelopeRsa { @@ -1013,26 +949,6 @@ export interface ExchangeLegacyBatchWithdrawRequest { planchets: ExchangeLegacyWithdrawRequest[]; } -export interface ExchangeRefreshRevealRequest { - new_denoms_h: HashCodeString[]; - coin_evs: CoinEnvelope[]; - /** - * kappa - 1 transfer private keys (ephemeral ECDHE keys). - */ - transfer_privs: string[]; - - transfer_pub: EddsaPublicKeyString; - - link_sigs: EddsaSignatureString[]; - - /** - * Iff the corresponding denomination has support for age restriction, - * the client MUST provide the original age commitment, i.e. the vector - * of public keys. - */ - old_age_commitment?: Edx25519PublicKeyEnc[]; -} - export interface ExchangeRefreshRevealRequestV2 { // The commitment from the /melt/ step, // i.e. the SHA512 value of @@ -1293,17 +1209,6 @@ export const codecForExchangeMeltResponse = (): Codec<ExchangeMeltResponse> => .property("refresh_base_url", codecOptional(codecForString())) .build("ExchangeMeltResponse"); -export const codecForExchangeRevealItem = (): Codec<ExchangeRevealItem> => - buildCodecForObject<ExchangeRevealItem>() - .property("ev_sig", codecForBlindedDenominationSignature()) - .build("ExchangeRevealItem"); - -export const codecForExchangeRevealResponse = - (): Codec<ExchangeRevealResponse> => - buildCodecForObject<ExchangeRevealResponse>() - .property("ev_sigs", codecForList(codecForExchangeRevealItem())) - .build("ExchangeRevealResponse"); - export interface FutureKeysResponse { future_denoms: any[]; @@ -1954,50 +1859,6 @@ export interface KycCheckInformation { fallback: string; } -export interface AmlDecisionDetails { - // Array of AML decisions made for this account. Possibly - // contains only the most recent decision if "history" was - // not set to 'true'. - aml_history: AmlDecisionDetail[]; - - // Array of KYC attributes obtained for this account. - kyc_attributes: KycDetail[]; -} - -export interface AmlDecisionDetail { - // What was the justification given? - justification: string; - - // What is the new AML state. - new_state: Integer; - - // When was this decision made? - decision_time: Timestamp; - - // What is the new AML decision threshold (in monthly transaction volume)? - new_threshold: AmountString; - - // Who made the decision? - decider_pub: AmlOfficerPublicKeyP; -} - -export interface KycDetail { - // Name of the configuration section that specifies the provider - // which was used to collect the KYC details - provider_section: string; - - // The collected KYC data. NULL if the attribute data could not - // be decrypted (internal error of the exchange, likely the - // attribute key was changed). - attributes?: object; - - // Time when the KYC data was collected - collection_time: Timestamp; - - // Time when the validity of the KYC data will expire - expiration_time: Timestamp; -} - export type AmlDecisionRequestWithoutSignature = Omit< AmlDecisionRequest, "officer_sig" @@ -2266,18 +2127,6 @@ export type ExchangeKycUploadFormRequest = { }; // Since **vATTEST**. -export interface KycCheckPublicInformation { - // English description of the check. - description: string; - - // Map from IETF BCP 47 language tags to localized - // description texts. - description_i18n?: { [lang_tag: string]: string }; - - // FIXME: is the above in any way sufficient - // to begin the check? Do we not need at least - // something more??!? -} export interface AmlStatisticsResponse { statistics: EventCounter[]; @@ -2662,28 +2511,6 @@ export interface GlobalFees { master_sig: EddsaSignatureString; } -export interface AggregateTransferFee { - // Per transfer wire transfer fee. - wire_fee: AmountString; - - // Per transfer closing fee. - closing_fee: AmountString; - - // What date (inclusive) does this fee go into effect? - // The different fees must cover the full time period in which - // any of the denomination keys are valid without overlap. - start_date: Timestamp; - - // What date (exclusive) does this fee stop going into effect? - // The different fees must cover the full time period in which - // any of the denomination keys are valid without overlap. - end_date: Timestamp; - - // Signature of TALER_MasterWireFeePS with - // purpose TALER_SIGNATURE_MASTER_WIRE_FEES. - sig: EddsaSignatureString; -} - // Binary representation of the age groups. // The bits set in the mask mark the edges at the beginning of a next age // group. F.e. for the age groups @@ -2823,14 +2650,6 @@ export const codecForLegitimizationMeasureDetails = .property("is_finished", codecForAny()) .build("TalerExchangeApi.LegitimizationMeasureDetails"); -export const codecForLegitimizationMeasures = - (): Codec<LegitimizationMeasures> => - buildCodecForObject<LegitimizationMeasures>() - .property("is_and_combinator", codecForAny()) - .property("verboten", codecForAny()) - .property("measures", codecForList(codecForMeasureInformation())) - .build("TalerExchangeApi.LegitimizationMeasures"); - export const codecForAvailableMeasureSummary = (): Codec<AvailableMeasureSummary> => buildCodecForObject<AvailableMeasureSummary>() @@ -2959,14 +2778,6 @@ export const codecForAmlDecisionsAccounts = (): Codec<AmlAccountsResponse> => // .property("decider_pub", codecForString()) // .build("TalerExchangeApi.AmlDecisionDetail"); -export const codecForKycDetail = (): Codec<KycDetail> => - buildCodecForObject<KycDetail>() - .property("provider_section", codecForString()) - .property("attributes", codecOptional(codecForAny())) - .property("collection_time", codecForTimestamp) - .property("expiration_time", codecForTimestamp) - .build("TalerExchangeApi.KycDetail"); - export const codecForAmlDecision = (): Codec<AmlDecision> => buildCodecForObject<AmlDecision>() .property("h_payto", codecForString()) @@ -3082,16 +2893,6 @@ export const codecForZeroLimitedOperation = (): Codec<ZeroLimitedOperation> => .property("rule_name", codecOptional(codecForString())) .build("TalerExchangeApi.ZeroLimitedOperation"); -export const codecForKycCheckPublicInformation = - (): Codec<KycCheckPublicInformation> => - buildCodecForObject<KycCheckPublicInformation>() - .property("description", codecForString()) - .property( - "description_i18n", - codecOptional(codecForInternationalizedString()), - ) - .build("TalerExchangeApi.KycCheckPublicInformation"); - export const codecForKycRequirementInformationId = (): Codec<KycRequirementInformationId> => codecForString() as Codec<KycRequirementInformationId>; @@ -3179,16 +2980,6 @@ export const codecForKycProcessStartInformation = .property("redirect_url", codecForURLString()) .build("TalerExchangeApi.KycProcessStartInformation"); -export interface BatchWithdrawResponse { - // Array of blinded signatures, in the same order as was - // given in the request. - ev_sigs: WithdrawResponse[]; -} -export interface WithdrawResponse { - // The blinded signature over the 'coin_ev', affirms the coin's - // validity after unblinding. - ev_sig: BlindedDenominationSignature; -} export type BlindedDenominationSignature = | RsaBlindedDenominationSignature | CSBlindedDenominationSignature; @@ -3218,262 +3009,6 @@ type HashCode = string; type EddsaSignature = string; type EddsaPublicKey = string; type Amount = AmountString; -type Base32 = string; - -export interface WithdrawError { - // Text describing the error. - hint: string; - - // Detailed error code. - code: Integer; - - // Amount left in the reserve. - balance: AmountString; - - // History of the reserve's activity, in the same format - // as returned by /reserve/$RID/history. - history: TransactionHistoryItem[]; -} -export type TransactionHistoryItem = - | AccountSetupTransaction - | ReserveWithdrawTransaction - | ReserveAgeWithdrawTransaction - | ReserveCreditTransaction - | ReserveClosingTransaction - | ReserveOpenRequestTransaction - | ReserveCloseRequestTransaction - | PurseMergeTransaction; - -enum TransactionHistoryType { - setup = "SETUP", - withdraw = "WITHDRAW", - ageWithdraw = "AGEWITHDRAW", - credit = "CREDIT", - closing = "CLOSING", - open = "OPEN", - close = "CLOSE", - merge = "MERGE", -} -interface AccountSetupTransaction { - type: TransactionHistoryType.setup; - - // Offset of this entry in the reserve history. - // Useful to request incremental histories via - // the "start" query parameter. - history_offset: Integer; - - // KYC fee agreed to by the reserve owner. - kyc_fee: AmountString; - - // Time when the KYC was triggered. - kyc_timestamp: Timestamp; - - // Hash of the wire details of the account. - // Note that this hash is unsalted and potentially - // private (as it could be inverted), hence access - // to this endpoint must be authorized using the - // private key of the reserve. - h_wire: HashCode; - - // Signature created with the reserve's private key. - // Must be of purpose TALER_SIGNATURE_ACCOUNT_SETUP_REQUEST over - // a TALER_AccountSetupRequestSignaturePS. - reserve_sig: EddsaSignature; -} -interface ReserveWithdrawTransaction { - type: "WITHDRAW"; - - // Offset of this entry in the reserve history. - // Useful to request incremental histories via - // the "start" query parameter. - history_offset: Integer; - - // Amount withdrawn. - amount: Amount; - - // Hash of the denomination public key of the coin. - h_denom_pub: HashCode; - - // Hash of the blinded coin to be signed. - h_coin_envelope: HashCode; - - // Signature over a TALER_WithdrawRequestPS - // with purpose TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW - // created with the reserve's private key. - reserve_sig: EddsaSignature; - - // Fee that is charged for withdraw. - withdraw_fee: Amount; -} -interface ReserveAgeWithdrawTransaction { - type: "AGEWITHDRAW"; - - // Offset of this entry in the reserve history. - // Useful to request incremental histories via - // the "start" query parameter. - history_offset: Integer; - - // Total Amount withdrawn. - amount: Amount; - - // Commitment of all n*kappa blinded coins. - h_commitment: HashCode; - - // Signature over a TALER_AgeWithdrawRequestPS - // with purpose TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW - // created with the reserve's private key. - reserve_sig: EddsaSignature; - - // Fee that is charged for withdraw. - withdraw_fee: Amount; -} -interface ReserveCreditTransaction { - type: "CREDIT"; - - // Offset of this entry in the reserve history. - // Useful to request incremental histories via - // the "start" query parameter. - history_offset: Integer; - - // Amount deposited. - amount: Amount; - - // Sender account payto:// URL. - sender_account_url: string; - - // Opaque identifier internal to the exchange that - // uniquely identifies the wire transfer that credited the reserve. - wire_reference: Integer; - - // Timestamp of the incoming wire transfer. - timestamp: Timestamp; -} -interface ReserveClosingTransaction { - type: "CLOSING"; - - // Offset of this entry in the reserve history. - // Useful to request incremental histories via - // the "start" query parameter. - history_offset: Integer; - - // Closing balance. - amount: Amount; - - // Closing fee charged by the exchange. - closing_fee: Amount; - - // Wire transfer subject. - wtid: Base32; - - // payto:// URI of the wire account into which the funds were returned to. - receiver_account_details: string; - - // This is a signature over a - // struct TALER_ReserveCloseConfirmationPS with purpose - // TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED. - exchange_sig: EddsaSignature; - - // Public key used to create 'exchange_sig'. - exchange_pub: EddsaPublicKey; - - // Time when the reserve was closed. - timestamp: Timestamp; -} -interface ReserveOpenRequestTransaction { - type: "OPEN"; - - // Offset of this entry in the reserve history. - // Useful to request incremental histories via - // the "start" query parameter. - history_offset: Integer; - - // Open fee paid from the reserve. - open_fee: Amount; - - // This is a signature over - // a struct TALER_ReserveOpenPS with purpose - // TALER_SIGNATURE_WALLET_RESERVE_OPEN. - reserve_sig: EddsaSignature; - - // Timestamp of the open request. - request_timestamp: Timestamp; - - // Requested expiration. - requested_expiration: Timestamp; - - // Requested number of free open purses. - requested_min_purses: Integer; -} -interface ReserveCloseRequestTransaction { - type: "CLOSE"; - - // Offset of this entry in the reserve history. - // Useful to request incremental histories via - // the "start" query parameter. - history_offset: Integer; - - // This is a signature over - // a struct TALER_ReserveClosePS with purpose - // TALER_SIGNATURE_WALLET_RESERVE_CLOSE. - reserve_sig: EddsaSignature; - - // Target account payto://, optional. - h_payto?: PaytoHash; - - // Timestamp of the close request. - request_timestamp: Timestamp; -} -interface PurseMergeTransaction { - type: "MERGE"; - - // Offset of this entry in the reserve history. - // Useful to request incremental histories via - // the "start" query parameter. - history_offset: Integer; - - // SHA-512 hash of the contact of the purse. - h_contract_terms: HashCode; - - // EdDSA public key used to approve merges of this purse. - merge_pub: EddsaPublicKey; - - // Minimum age required for all coins deposited into the purse. - min_age: Integer; - - // Number that identifies who created the purse - // and how it was paid for. - flags: Integer; - - // Purse public key. - purse_pub: EddsaPublicKey; - - // EdDSA signature of the account/reserve affirming the merge - // over a TALER_AccountMergeSignaturePS. - // Must be of purpose TALER_SIGNATURE_ACCOUNT_MERGE - reserve_sig: EddsaSignature; - - // Client-side timestamp of when the merge request was made. - merge_timestamp: Timestamp; - - // Indicative time by which the purse should expire - // if it has not been merged into an account. At this - // point, all of the deposits made should be - // auto-refunded. - purse_expiration: Timestamp; - - // Purse fee the reserve owner paid for the purse creation. - purse_fee: Amount; - - // Total amount merged into the reserve. - // (excludes fees). - amount: Amount; - - // True if the purse was actually merged. - // If false, only the purse_fee has an impact - // on the reserve balance! - merged: boolean; -} - /** * Docs name: WithdrawRequest */ @@ -3605,42 +3140,6 @@ interface PurseContractConflict { contract_pub: EddsaPublicKey; } -export interface PurseCreate { - // Total value of the purse, excluding fees. - amount: Amount; - - // Minimum age required for all coins deposited into the purse. - min_age: Integer; - - // Optional encrypted contract, in case the buyer is - // proposing the contract and thus establishing the - // purse with the payment. - econtract?: EncryptedContract; - - // EdDSA public key used to approve merges of this purse. - merge_pub: EddsaPublicKey; - - // EdDSA signature of the purse over a - // TALER_PurseRequestSignaturePS - // of purpose TALER_SIGNATURE_WALLET_PURSE_CREATE - // confirming the key - // invariants associated with the purse. - // (amount, h_contract_terms, expiration). - purse_sig: EddsaSignature; - - // SHA-512 hash of the contact of the purse. - h_contract_terms: HashCode; - - // Array of coins being deposited into the purse. - // Maximum length is 128. - deposits: PurseDeposit[]; - - // Indicative time by which the purse should expire - // if it has not been merged into an account. At this - // point, all of the deposits made will be auto-refunded. - purse_expiration: Timestamp; -} - export const codecForPurseConflict = (): Codec<PurseConflict> => buildCodecForUnion<PurseConflict>() .discriminateOn("code") diff --git a/packages/taler-util/src/types-taler-kyc-aml.ts b/packages/taler-util/src/types-taler-kyc-aml.ts @@ -35,37 +35,6 @@ export type AmlProgram = ( config: string | undefined, ) => Promise<AmlOutcome>; -export type KycConverter = ( - input: object | undefined, - config: string | undefined, -) => object; - -export type AmlProgramParams = { - name: string; - debug?: boolean; - showVersion?: boolean; - showRequiredContext?: boolean; - showRequiredAttributes?: boolean; - showRequiredInputs?: boolean; - showHelp?: boolean; - config?: string; -}; - -export type KycConverterParams = { - name: string; - debug?: boolean; - showVersion?: boolean; - showOutputs?: boolean; - showHelp?: boolean; - config?: string; -}; - -export type KycConverterDefinition = { - name: string; - logic: KycConverter; - outputs: string[]; -}; - export type AmlProgramDefinition = { name: string; requiredContext: string[]; diff --git a/packages/taler-util/src/types-taler-mailbox.ts b/packages/taler-util/src/types-taler-mailbox.ts @@ -20,7 +20,6 @@ import { codecForAmountString } from "./amounts.js"; import { Codec, buildCodecForObject, - buildCodecForUnion, codecForNumber, codecOptional, } from "./codec.js"; @@ -93,32 +92,6 @@ export interface MailboxRegisterPaymentRequired { talerUri?: string; } -export const codecForMailboxRegisterOk = (): Codec<MailboxRegisterOk> => - buildCodecForObject<MailboxRegisterOk>() - .property("status", codecForConstString("ok")) - .build("MailboxRegisterOk"); - -export const codecForMailboxRegisterPaymentRequired = - (): Codec<MailboxRegisterPaymentRequired> => - buildCodecForObject<MailboxRegisterPaymentRequired>() - .property("status", codecForConstString("payment-required")) - .property("talerUri", codecOptional(codecForString())) - .build("MailboxRegisterPaymentRequired"); - -export const codecForMailboxRegisterResult = (): Codec<MailboxRegisterResult> => - buildCodecForUnion<MailboxRegisterResult>() - .discriminateOn("status") - .alternative("ok", codecForMailboxRegisterOk()) - .alternative("payment-required", codecForMailboxRegisterPaymentRequired()) - .build("MailboxRegisterResult"); - -export const codecForTalerMailboxRegisterRequest = - (): Codec<MailboxRegisterRequest> => - buildCodecForObject<MailboxRegisterRequest>() - .property("mailbox_metadata", codecForTalerMailboxMetadata()) - .property("signature", codecForString()) - .build("TalerMailboxApi.MailboxRegisterRequest"); - export interface MailboxRegisterRequest { // Mailbox metadata. mailbox_metadata: MailboxMetadata; @@ -136,7 +109,10 @@ export const codecForTalerMailboxMetadata = (): Codec<MailboxMetadata> => .property("signing_key", codecForEddsaPublicKey()) .property("signing_key_type", codecOptional(codecForConstString("EdDSA"))) .property("encryption_key", codecForString()) - .property("encryption_key_type", codecOptional(codecForConstString("X25519"))) + .property( + "encryption_key_type", + codecOptional(codecForConstString("X25519")), + ) .property("expiration", codecForTimestamp) .build("TalerMailboxApi.MailboxMessageKeys"); diff --git a/packages/taler-util/src/types-taler-merchant.ts b/packages/taler-util/src/types-taler-merchant.ts @@ -16,9 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later */ -import { codecForAmountString, - codecForCurrency, -} from "./amounts.js"; +import { codecForAmountString, codecForCurrency } from "./amounts.js"; import { Codec, buildCodecForObject, @@ -30,12 +28,26 @@ import { codecOptional, } from "./codec.js"; import { CancellationToken } from "./CancellationToken.js"; -import { ObjectCodec, buildCodecForUnion, codecForConstNumber, codecForConstString, codecForEither, codecForMap, codecForStringURL, codecOptionalDefault } from "./codec.js"; +import { + ObjectCodec, + buildCodecForUnion, + codecForConstNumber, + codecForConstString, + codecForEither, + codecForMap, + codecForStringURL, + codecOptionalDefault, +} from "./codec.js"; import { assertUnreachable } from "./errors.js"; import { PaytoString, codecForPaytoString } from "./payto.js"; import { codecForTalerUriString } from "./taleruri.js"; import { AccessToken } from "./types-taler-common.js"; -import { AccountLimit, DenomKeyType, ExchangeWireAccount, UnblindedDenominationSignature, codecForAccountLimit, codecForExchangeWireAccount } from "./types-taler-exchange.js"; +import { + AccountLimit, + DenomKeyType, + UnblindedDenominationSignature, + codecForAccountLimit, +} from "./types-taler-exchange.js"; import { AbsoluteTime, Duration, @@ -79,25 +91,6 @@ import { import { PayWalletData, codecForCanonBaseUrl } from "./types-taler-wallet.js"; import { TalerUriString } from "./taleruri.js"; -/** - * Proposal returned from the contract URL. - * - * Doc name: api-merchant/ClaimResponse. - */ -export interface MerchantClaimResponse { - /** - * Contract terms for the propoal. - * Raw, un-decoded JSON object. - */ - contract_terms?: any; - - /** - * Signature over contract, made by the merchant. The public key used for signing - * must be contract_terms.merchant_pub. - */ - sig: string; -} - export type TokenEnvelope = TokenEnvelopeRsa | TokenEnvelopeCs; export interface TokenEnvelopeRsa { @@ -200,36 +193,6 @@ export class CheckPaymentResponse { contract_url?: string | undefined; } -export const codecForMerchantRefundPermission = - (): Codec<MerchantAbortPayRefundDetails> => - buildCodecForObject<MerchantAbortPayRefundDetails>() - .property("refund_amount", codecForAmountString()) - .property("refund_fee", codecForAmountString()) - .property("coin_pub", codecForString()) - .property("rtransaction_id", codecForNumber()) - .property("exchange_http_status", codecForNumber()) - .property("exchange_code", codecOptional(codecForNumber())) - .property("exchange_reply", codecOptional(codecForAny())) - .property("exchange_sig", codecOptional(codecForString())) - .property("exchange_pub", codecOptional(codecForString())) - .build("MerchantRefundPermission"); - -export const codecForMerchantClaimResponse = (): Codec<MerchantClaimResponse> => - buildCodecForObject<MerchantClaimResponse>() - .property("contract_terms", codecForMerchantContractTerms()) - .property("sig", codecForString()) - .build("MerchantClaimResponse"); - -export const codecForCheckPaymentResponse = (): Codec<CheckPaymentResponse> => - buildCodecForObject<CheckPaymentResponse>() - .property("order_status", codecForString()) - .property("refunded", codecOptional(codecForBoolean())) - .property("refunded_amount", codecOptional(codecForString())) - .property("contract_terms", codecOptional(codecForAny())) - .property("taler_pay_uri", codecOptional(codecForString())) - .property("contract_url", codecOptional(codecForString())) - .build("CheckPaymentResponse"); - export type MerchantCoinRefundStatus = | MerchantCoinRefundSuccessStatus | MerchantCoinRefundFailureStatus; @@ -428,23 +391,6 @@ export interface MerchantAbortPayRefundSuccessStatus { exchange_pub: string; } -export interface AuditorHandle { - /** - * Official name of the auditor. - */ - name: string; - - /** - * Master public signing key of the auditor. - */ - auditor_pub: EddsaPublicKeyString; - - /** - * Base URL of the auditor. - */ - url: string; -} - // Delivery location, loosely modeled as a subset of // ISO20022's PostalAddress25. export interface Location { @@ -893,75 +839,6 @@ export interface MerchantContractDiscountTokenDetails { expected_domains: string[]; } -/** - * Refund permission in the format that the merchant gives it to us. - */ -export interface MerchantAbortPayRefundDetails { - /** - * Amount to be refunded. - */ - refund_amount: AmountString; - - /** - * Fee for the refund. - */ - refund_fee: AmountString; - - /** - * Public key of the coin being refunded. - */ - coin_pub: string; - - /** - * Refund transaction ID between merchant and exchange. - */ - rtransaction_id: number; - - /** - * Exchange's key used for the signature. - */ - exchange_pub?: string; - - /** - * Exchange's signature to confirm the refund. - */ - exchange_sig?: string; - - /** - * Error replay from the exchange (if any). - */ - exchange_reply?: any; - - /** - * Error code from the exchange (if any). - */ - exchange_code?: number; - - /** - * HTTP status code of the exchange's response - * to the merchant's refund request. - */ - exchange_http_status: number; -} - -/** - * Reserve signature, defined as separate class to facilitate - * schema validation. - */ -export interface MerchantBlindSigWrapperV1 { - /** - * Reserve signature. - */ - blind_sig: string; -} - -export const codecForAuditorHandle = (): Codec<AuditorHandle> => - buildCodecForObject<AuditorHandle>() - .property("name", codecForString()) - .property("auditor_pub", codecForEddsaPublicKey()) - .property("url", codecForString()) - .build("AuditorHandle"); - export const codecForLocation = (): Codec<Location> => buildCodecForObject<Location>() .property("country", codecOptional(codecForString())) @@ -1387,15 +1264,6 @@ export interface UnclaimRequest { h_contract: HashCodeString; } -export interface PaymentResponse { - // Signature on TALER_PaymentResponsePS with the public - // key of the merchant instance. - sig: EddsaSignatureString; - - // Text to be shown to the point-of-sale staff as a proof of - // payment. - pos_confirmation?: string; -} export interface PaymentDeniedLegallyResponse { // Numeric error code identifying whether the exchange refused the payment // outright or because of a transaction limit. @@ -1921,16 +1789,14 @@ export interface InstanceAuthConfigurationMessage { } /** Authentication configuration for the current instance. */ -export interface InstanceAuthChangeRequest - extends InstanceAuthConfigurationMessage { +export interface InstanceAuthChangeRequest extends InstanceAuthConfigurationMessage { // Current password used to re-authenticate the request. // @since merchant protocol **v40**. old_password: string; } /** Authentication configuration used by public account recovery. */ -export interface ForgotPasswordRequest - extends InstanceAuthConfigurationMessage { +export interface ForgotPasswordRequest extends InstanceAuthConfigurationMessage { token_duration?: RelativeTime; } @@ -2335,20 +2201,6 @@ export interface MerchantAccountKycRedirect { tos_accepted_early?: string; } -export interface ExchangeKycTimeout { - // Base URL of the exchange this is about. - exchange_url: string; - - // Numeric error code indicating errors the exchange - // returned, or TALER_EC_INVALID for none. - exchange_code: number; - - // HTTP status code returned by the exchange when we asked for - // information about the KYC status. - // 0 if there was no response at all. - exchange_http_status: number; -} - export interface AccountAddDetails { // payto:// URI of the account. payto_uri: PaytoString; @@ -2551,11 +2403,6 @@ export interface CategoryCreateRequest { name_i18n?: { [lang_tag: string]: string }; } -export interface CategoryCreatedResponse { - // Number of the newly created category. - category_id: Integer; -} - export interface ProductAddDetailRequest { // Product ID to use. product_id: string; @@ -2892,25 +2739,6 @@ export interface PostOrderRequest { export type Order = OrderV0 | OrderV1; -export interface MinimalOrderDetail { - // Amount to be paid by the customer. - amount: AmountString; - - // Short summary of the order. - summary: string; - - // See documentation of fulfillment_url in ContractTerms. - // Either fulfillment_url or fulfillment_message must be specified. - // When creating an order, the fulfillment URL can - // contain ${ORDER_ID} which will be substituted with the - // order ID of the newly created order. - fulfillment_url?: string; - - // See documentation of fulfillment_message in ContractTerms. - // Either fulfillment_url or fulfillment_message must be specified. - fulfillment_message?: string; -} - export interface MinimalInventoryProduct { // Which product is requested (here mandatory!). product_id: string; @@ -4405,27 +4233,6 @@ export interface Tax { tax: AmountString; } -export interface Merchant { - // The merchant's legal name of business. - name: string; - - // Label for a location with the business address of the merchant. - email?: string; - - // Label for a location with the business address of the merchant. - website?: string; - - // An optional base64-encoded product image. - logo?: ImageDataUrl; - - // Label for a location with the business address of the merchant. - address?: Location; - - // Label for a location that denotes the jurisdiction for disputes. - // Some of the typical fields for a location (such as a street address) may be absent. - jurisdiction?: Location; -} - // Delivery location, loosely modeled as a subset of // ISO20022's PostalAddress25. export interface Location { @@ -4487,68 +4294,6 @@ export interface Exchange { max_contribution?: AmountString; } -export interface MerchantReserveCreateConfirmation { - // Public key identifying the reserve. - reserve_pub: EddsaPublicKey; - - // Wire accounts of the exchange where to transfer the funds. - accounts: ExchangeWireAccount[]; -} - -export interface TemplateEditableDetails { - // Human-readable summary for the template. - summary?: string; - - // Required currency for payments to the template. - // The user may specify any amount, but it must be - // in this currency. - // This parameter is optional and should not be present - // if "amount" is given. - currency?: string; - - // The price is imposed by the merchant and cannot be changed by the customer. - // This parameter is optional. - amount?: AmountString; -} - -export interface MerchantTemplateContractDetails { - // Human-readable summary for the template. - summary?: string; - - // The price is imposed by the merchant and cannot be changed by the customer. - // This parameter is optional. - amount?: string; - - // Minimum age buyer must have (in years). Default is 0. - minimum_age: number; - - // The time the customer need to pay before his order will be deleted. - // It is deleted if the customer did not pay and if the duration is over. - pay_duration: TalerProtocolDuration; -} - -export interface MerchantTemplateAddDetails { - // Template ID to use. - template_id: string; - - // Human-readable description for the template. - template_description: string; - - // A base64-encoded image selected by the merchant. - // This parameter is optional. - // We are not sure about it. - image?: string; - - editable_defaults?: TemplateEditableDetails; - - // Additional information in a separate template. - template_contract: MerchantTemplateContractDetails; - - // OTP device ID. - // This parameter is optional. - otp_id?: string; -} - export interface ExchangeStatusResponse { exchanges: ExchangeStatusDetail[]; } @@ -4631,7 +4376,7 @@ export const codecForTalerMerchantConfigResponse = .property("implementation", codecOptional(codecForString())) .property( "have_self_provisioning", - + // Safe for an optional field: this never yields undefined. Codec<V> // describes output, not which inputs are tolerated. codecOptionalDefault(codecForBoolean(), false) as unknown as Codec< @@ -4656,7 +4401,7 @@ export const codecForTalerMerchantConfigResponse = .property("default_wire_transfer_delay", codecOptional(codecForDuration)) .property( "payment_target_regex", - + // Safe for an optional field: this never yields undefined. Codec<V> // describes output, not which inputs are tolerated. codecOptionalDefault(codecForString(), "*") as unknown as Codec< @@ -4692,12 +4437,6 @@ export const codecForClaimResponse = (): Codec<ClaimResponse> => .property("sig", codecForEddsaSignature()) .build("TalerMerchantApi.ClaimResponse"); -export const codecForPaymentResponse = (): Codec<PaymentResponse> => - buildCodecForObject<PaymentResponse>() - .property("pos_confirmation", codecOptional(codecForString())) - .property("sig", codecForEddsaSignature()) - .build("TalerMerchantApi.PaymentResponse"); - export const codecForPaymentDeniedLegallyResponse = (): Codec<PaymentDeniedLegallyResponse> => buildCodecForObject<PaymentDeniedLegallyResponse>() @@ -4910,7 +4649,7 @@ export const codecForMerchantAccountKycRedirect = .property("payto_kycauths", codecOptional(codecForList(codecForString()))) .property( "kyc_swap_tos_acceptance", - + // Safe for an optional field: this never yields undefined. Codec<V> // describes output, not which inputs are tolerated. codecOptionalDefault(codecForBoolean(), false) as unknown as Codec< @@ -4947,13 +4686,6 @@ export const codecForLoginTokenSuccessResponse = .deprecatedProperty("token") .build("TalerMerchantApi.LoginTokenSuccessResponse"); -export const codecForExchangeKycTimeout = (): Codec<ExchangeKycTimeout> => - buildCodecForObject<ExchangeKycTimeout>() - .property("exchange_url", codecForURLString()) - .property("exchange_code", codecForNumber()) - .property("exchange_http_status", codecForNumber()) - .build("TalerMerchantApi.ExchangeKycTimeout"); - export const codecForAccountAddResponse = (): Codec<AccountAddResponse> => buildCodecForObject<AccountAddResponse>() .property("h_wire", codecForString()) @@ -5114,16 +4846,6 @@ export const codecForOrderHistoryEntry = (): Codec<OrderHistoryEntry> => .property("wired", codecOptional(codecForBoolean())) .build("TalerMerchantApi.OrderHistoryEntry"); -export const codecForMerchant = (): Codec<Merchant> => - buildCodecForObject<Merchant>() - .property("name", codecForString()) - .property("email", codecOptional(codecForString())) - .property("logo", codecOptional(codecForString())) - .property("website", codecOptional(codecForString())) - .property("address", codecOptional(codecForLocation())) - .property("jurisdiction", codecOptional(codecForLocation())) - .build("TalerMerchantApi.MerchantInfo"); - export const codecForExchange = (): Codec<Exchange> => buildCodecForObject<Exchange>() .property("master_pub", codecForEddsaPublicKey()) @@ -5132,54 +4854,6 @@ export const codecForExchange = (): Codec<Exchange> => .property("max_contribution", codecOptional(codecForAmountString())) .build("TalerMerchantApi.Exchange"); -const codecForOrderCommon = (): ObjectCodec<OrderCommon> => - buildCodecForObject<Order>() - .property("order_id", codecOptional(codecForString())) - .property("public_reorder_url", codecOptional(codecForString())) - .property("fulfillment_url", codecOptional(codecForString())) - .property("fulfillment_message", codecOptional(codecForString())) - .property( - "fulfillment_message_i18n", - codecOptional(codecForInternationalizedString()), - ) - .property("merchant_base_url", codecOptional(codecForString())) - .property("auto_refund", codecOptional(codecForDuration)) - .property("summary", codecForString()) - .property("summary_i18n", codecOptional(codecForInternationalizedString())) - .property("pay_deadline", codecOptional(codecForTimestamp)) - .property("refund_deadline", codecOptional(codecForTimestamp)) - .property("wire_transfer_deadline", codecOptional(codecForTimestamp)) - .property("timestamp", codecOptional(codecForTimestamp)) - .property("delivery_location", codecOptional(codecForLocation())) - .property("delivery_date", codecOptional(codecForTimestamp)) - .property("products", codecOptional(codecForList(codecForProductSold()))) - .property("extra", codecOptional(codecForAny())) - .property("order_default_money_pot", codecOptional(codecForNumber())) - .build("TalerMerchantApi.Order"); - -export const codecForOrderV0 = (): Codec<OrderV0> => - buildCodecForObject<OrderV0>() - .property("version", codecOptional(codecForConstNumber(OrderVersion.V0))) - .property("amount", codecForAmountString()) - .property("max_fee", codecOptional(codecForAmountString())) - .mixin(codecForOrderCommon()) - .build("TalerMerchantApi.OrderV0"); - -export const codecForOrderV1 = (): Codec<OrderV1> => - buildCodecForObject<OrderV1>() - .property("version", codecForConstNumber(OrderVersion.V1)) - .property("choices", codecOptional(codecForList(codecForOrderChoice()))) - .mixin(codecForOrderCommon()) - .build("TalerMerchantApi.OrderV1"); - -export const codecForOrder = (): Codec<Order> => - buildCodecForUnion<Order>() - .discriminateOn("version") - .alternative(undefined, codecForOrderV0()) - .alternative(OrderVersion.V0, codecForOrderV0()) - .alternative(OrderVersion.V1, codecForOrderV1()) - .build("TalerMerchantApi.Order"); - export const codecForOrderChoice = (): Codec<OrderChoice> => buildCodecForObject<OrderChoice>() .property("amount", codecForAmountString()) @@ -5312,16 +4986,6 @@ export const codecForGetSessionStatusPaidResponse = .property("order_id", codecForString()) .build("TalerMerchantApi.GetSessionStatusPaidResponse"); -export interface GetSessionStatusUnpaidResponse { - // Order ID of the unpaid order. - order_id: string; -} -export const codecForGetSessionStatusUnpaidResponse = - (): Codec<GetSessionStatusUnpaidResponse> => - buildCodecForObject<GetSessionStatusUnpaidResponse>() - .property("order_id", codecForString()) - .build("TalerMerchantApi.GetSessionStatusUnpaidResponse"); - export const codecForRefundDetails = (): Codec<RefundDetails> => buildCodecForObject<RefundDetails>() .property("reason", codecForString()) @@ -5480,21 +5144,23 @@ export const codecForTemplateContractInventoryCart = .property("selected_all", codecOptional(codecForBoolean())) .property( "selected_categories", - + // Safe for an optional field: this never yields undefined. Codec<V> // describes output, not which inputs are tolerated. - codecOptionalDefault(codecForList(codecForNumber()), []) as unknown as Codec< - number[] | undefined - >, + codecOptionalDefault( + codecForList(codecForNumber()), + [], + ) as unknown as Codec<number[] | undefined>, ) .property( "selected_products", - + // Safe for an optional field: this never yields undefined. Codec<V> // describes output, not which inputs are tolerated. - codecOptionalDefault(codecForList(codecForString()), []) as unknown as Codec< - string[] | undefined - >, + codecOptionalDefault( + codecForList(codecForString()), + [], + ) as unknown as Codec<string[] | undefined>, ) .property("inventory_payload", codecOptional(codecForAny())) // FIXME: validate @@ -5630,7 +5296,10 @@ export const codecForTokenFamilySummary = (): Codec<TokenFamilySummary> => .property("slug", codecForString()) .property("name", codecForString()) .property("description", codecForString()) - .property("description_i18n", codecOptional(codecForInternationalizedString())) + .property( + "description_i18n", + codecOptional(codecForInternationalizedString()), + ) .property("valid_after", codecForTimestamp) .property("valid_before", codecForTimestamp) .property("kind", codecForTokenFamilyKind) @@ -5710,21 +5379,6 @@ export const codecForInstance = (): Codec<Instance> => .property("deleted", codecForBoolean()) .build("TalerMerchantApi.Instance"); -export const codecForTemplateEditableDetails = - (): Codec<TemplateEditableDetails> => - buildCodecForObject<TemplateEditableDetails>() - .property("summary", codecOptional(codecForString())) - .property("currency", codecOptional(codecForString())) - .property("amount", codecOptional(codecForAmountString())) - .build("TemplateEditableDetails"); - -export const codecForMerchantReserveCreateConfirmation = - (): Codec<MerchantReserveCreateConfirmation> => - buildCodecForObject<MerchantReserveCreateConfirmation>() - .property("accounts", codecForList(codecForExchangeWireAccount())) - .property("reserve_pub", codecForEddsaPublicKey()) - .build("MerchantReserveCreateConfirmation"); - export interface ChallengeResponse { // List of challenge IDs that must be solved before the // client may proceed. diff --git a/packages/taler-util/src/types-taler-prepared-transfer.ts b/packages/taler-util/src/types-taler-prepared-transfer.ts @@ -21,7 +21,6 @@ import { Codec, buildCodecForObject, buildCodecForUnion, - codecForBoolean, codecForConstString, codecForEither, codecForList, @@ -34,8 +33,6 @@ import { EddsaPublicKey, EddsaSignature, Timestamp, - codecForEddsaPublicKey, - codecForEddsaSignature, } from "./types-taler-common.js"; export type SubjectFormat = "SIMPLE" | "URI" | "CH_QR_BILL"; @@ -143,13 +140,12 @@ export interface Unregistration { authorization_sig: EddsaSignature; } -export const codeForSubjectFormat = - (): Codec<SubjectFormat> => - codecForEither( - codecForConstString("SIMPLE"), - codecForConstString("URI"), - codecForConstString("CH_QR_BILL"), - ); +export const codeForSubjectFormat = (): Codec<SubjectFormat> => + codecForEither( + codecForConstString("SIMPLE"), + codecForConstString("URI"), + codecForConstString("CH_QR_BILL"), + ); export const codecForPreparedTransferConfig = (): Codec<PreparedTransferConfig> => @@ -161,69 +157,37 @@ export const codecForPreparedTransferConfig = .property("version", codecForString()) .build("TalerPreparedTransferApi.PreparedTransferConfig"); -export const codecForRegistrationRequest = - (): Codec<RegistrationRequest> => - buildCodecForObject<RegistrationRequest>() - .property("credit_amount", codecForAmountString()) - .property( - "type", - codecForEither( - codecForConstString("reserve"), - codecForConstString("kyc"), - ), - ) - .property("credit_account", codecForString()) - .property("alg", codecForEither(codecForConstString("EdDSA"))) - .property("account_pub", codecForEddsaPublicKey()) - .property("authorization_pub", codecForEddsaPublicKey()) - .property("authorization_sig", codecForEddsaSignature()) - .property("recurrent", codecForBoolean()) - .build("TalerWireGatewayApi.RegistrationRequest"); - -export const codecForTransferSubject = - (): Codec<TransferSubject> => - buildCodecForUnion<TransferSubject>() - .discriminateOn("type") - .alternative("SIMPLE", codecForSimpleSubject()) - .alternative("URI", codecForUriSubject()) - .alternative("CH_QR_BILL", codecForSwissQrBillSubject()) - .build("TalerPreparedTransferApi.TransferSubject"); - -export const codecForSimpleSubject = - (): Codec<SimpleSubject> => - buildCodecForObject<SimpleSubject>() - .property("type", codecForConstString("SIMPLE")) - .property("credit_amount", codecForAmountString()) - .property("subject", codecForString()) - .build("TalerPreparedTransferApi.SimpleSubject"); - -export const codecForUriSubject = - (): Codec<UriSubject> => - buildCodecForObject<UriSubject>() - .property("type", codecForConstString("URI")) - .property("credit_amount", codecForAmountString()) - .property("uri", codecForString()) - .build("TalerPreparedTransferApi.UriSubject"); - -export const codecForSwissQrBillSubject = - (): Codec<SwissQrBillSubject> => - buildCodecForObject<SwissQrBillSubject>() - .property("type", codecForConstString("CH_QR_BILL")) - .property("credit_amount", codecForAmountString()) - .property("qr_reference_number", codecForString()) - .build("TalerPreparedTransferApi.SwissQrBillSubject"); - -export const codecForRegistrationResponse = - (): Codec<RegistrationResponse> => - buildCodecForObject<RegistrationResponse>() - .property("subjects", codecForList(codecForTransferSubject())) - .property("expiration", codecForTimestamp) - .build("TalerWireGatewayApi.RegistrationResponse"); - -export const codecForUnregistration = - (): Codec<Unregistration> => - buildCodecForObject<Unregistration>() - .property("timestamp", codecForTimestamp) - .property("authorization_pub", codecForEddsaPublicKey()) - .property("authorization_sig", codecForEddsaSignature()) - .build("TalerPreparedTransferApi.Unregistration"); +export const codecForTransferSubject = (): Codec<TransferSubject> => + buildCodecForUnion<TransferSubject>() + .discriminateOn("type") + .alternative("SIMPLE", codecForSimpleSubject()) + .alternative("URI", codecForUriSubject()) + .alternative("CH_QR_BILL", codecForSwissQrBillSubject()) + .build("TalerPreparedTransferApi.TransferSubject"); + +export const codecForSimpleSubject = (): Codec<SimpleSubject> => + buildCodecForObject<SimpleSubject>() + .property("type", codecForConstString("SIMPLE")) + .property("credit_amount", codecForAmountString()) + .property("subject", codecForString()) + .build("TalerPreparedTransferApi.SimpleSubject"); + +export const codecForUriSubject = (): Codec<UriSubject> => + buildCodecForObject<UriSubject>() + .property("type", codecForConstString("URI")) + .property("credit_amount", codecForAmountString()) + .property("uri", codecForString()) + .build("TalerPreparedTransferApi.UriSubject"); + +export const codecForSwissQrBillSubject = (): Codec<SwissQrBillSubject> => + buildCodecForObject<SwissQrBillSubject>() + .property("type", codecForConstString("CH_QR_BILL")) + .property("credit_amount", codecForAmountString()) + .property("qr_reference_number", codecForString()) + .build("TalerPreparedTransferApi.SwissQrBillSubject"); + +export const codecForRegistrationResponse = (): Codec<RegistrationResponse> => + buildCodecForObject<RegistrationResponse>() + .property("subjects", codecForList(codecForTransferSubject())) + .property("expiration", codecForTimestamp) + .build("TalerWireGatewayApi.RegistrationResponse"); diff --git a/packages/taler-util/src/types-taler-sync.ts b/packages/taler-util/src/types-taler-sync.ts @@ -1,44 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2024 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU Affero 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 Affero General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - - SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import { AmountString } from "./types-taler-common.js"; - -export interface BackupRecovery { - walletRootPriv: string; - providers: { - name: string; - url: string; - }[]; -} - -export class BackupBackupProviderTerms { - /** - * Last known supported protocol version. - */ - supported_protocol_version: string; - - /** - * Last known annual fee. - */ - annual_fee: AmountString; - - /** - * Last known storage limit. - */ - storage_limit_in_megabytes: number; -} diff --git a/packages/taler-util/src/types-taler-wallet-transactions.ts b/packages/taler-util/src/types-taler-wallet-transactions.ts @@ -29,11 +29,9 @@ import { Codec, buildCodecForObject, - codecForAny, codecForBoolean, codecForConstString, codecForEither, - codecForList, codecForNumber, codecForString, codecOptional, @@ -45,15 +43,10 @@ import { codecForPreciseTimestamp, } from "./time.js"; import type { TalerUriString } from "./taleruri.js"; -import { - AmountString, - InternationalizedString, - codecForInternationalizedString, -} from "./types-taler-common.js"; +import { AmountString, InternationalizedString } from "./types-taler-common.js"; import { MerchantContractTerms, MerchantInfo, - codecForMerchantInfo, } from "./types-taler-merchant.js"; import { RefreshReason, @@ -1084,36 +1077,11 @@ export const codecForTransactionsRequest = (): Codec<TransactionsRequest> => .build("TransactionsRequest"); // FIXME: do full validation here! -export const codecForTransactionsResponse = (): Codec<TransactionsResponse> => - buildCodecForObject<TransactionsResponse>() - .property("transactions", codecForList(codecForAny())) - .build("TransactionsResponse"); - -export const codecForOrderShortInfo = (): Codec<OrderShortInfo> => - buildCodecForObject<OrderShortInfo>() - .property("contractTermsHash", codecForString()) - .property("fulfillmentMessage", codecOptional(codecForString())) - .property( - "fulfillmentMessage_i18n", - codecOptional(codecForInternationalizedString()), - ) - .property("fulfillmentUrl", codecOptional(codecForString())) - .property("merchant", codecForMerchantInfo()) - .property("orderId", codecForString()) - .property("summary", codecForString()) - .property("summary_i18n", codecOptional(codecForInternationalizedString())) - .build("OrderShortInfo"); export interface ListAssociatedRefreshesRequest { transactionId: string; } -export const codecForListAssociatedRefreshesRequest = - (): Codec<ListAssociatedRefreshesRequest> => - buildCodecForObject<ListAssociatedRefreshesRequest>() - .property("transactionId", codecForString()) - .build("ListAssociatedRefreshesRequest"); - export interface ListAssociatedRefreshesResponse { transactionIds: string[]; } diff --git a/packages/taler-util/src/types-taler-wallet.ts b/packages/taler-util/src/types-taler-wallet.ts @@ -41,7 +41,6 @@ import { codecForConstString, codecForEither, codecForList, - codecForMap, codecForNumber, codecForString, codecForStringEnum, @@ -60,7 +59,6 @@ import { TalerUri, TalerUriString, TemplateParams, - codecForTalerUriString, } from "./taleruri.js"; import { AbsoluteTime, @@ -71,7 +69,6 @@ import { codecForAbsoluteTime, codecForDuration, codecForTimestamp, - codecForPreciseTimestamp, } from "./time.js"; import { BlindedDonationReceiptKeyPair } from "./types-donau.js"; import { WithdrawalOperationStatusFlag } from "./types-taler-bank-integration.js"; @@ -89,7 +86,6 @@ import { } from "./types-taler-common.js"; import { AccountRestriction, - AuditorDenomSig, CoinEnvelope, DenomKeyType, DenominationPubKey, @@ -100,7 +96,6 @@ import { PartialPeerContractTerms, PeerContractTerms, UnblindedDenominationSignature, - codecForExchangeWireAccount, codecForPartialPeerContractTerms, codecForPeerContractTerms, } from "./types-taler-exchange.js"; @@ -112,9 +107,7 @@ import { TokenEnvelope, TokenIssuePublicKey, WalletTemplateDetailsResponse, - codecForMerchantContractTermsV0, } from "./types-taler-merchant.js"; -import { BackupRecovery } from "./types-taler-sync.js"; import { TransactionMajorState, TransactionMinorState, @@ -259,22 +252,6 @@ export const codecForScopeInfo = (): Codec<ScopeInfo> => ) .build("ScopeInfo"); -/** - * Response for the create reserve request to the wallet. - */ -export class CreateReserveResponse { - /** - * Exchange URL where the bank should create the reserve. - * The URL is canonicalized in the response. - */ - exchange: string; - - /** - * Reserve public key of the newly created reserve. - */ - reservePub: string; -} - export interface GetBalanceDetailRequest { currency: string; } @@ -448,12 +425,6 @@ export interface AmountResponse { rawAmount: AmountString; } -export const codecForAmountResponse = (): Codec<AmountResponse> => - buildCodecForObject<AmountResponse>() - .property("effectiveAmount", codecForAmountString()) - .property("rawAmount", codecForAmountString()) - .build("AmountResponse"); - export enum BalanceFlag { IncomingKyc = "incoming-kyc", IncomingAml = "incoming-aml", @@ -529,11 +500,6 @@ export interface GetCurrencySpecificationResponse { currencySpecification: CurrencySpecification; } -export interface BuiltinExchange { - exchangeBaseUrl: string; - currencyHint: string; -} - /** * Coin selection algorithm the wallet uses when spending. * @@ -771,37 +737,6 @@ export interface BalancesResponse { donauSummary?: DonauSummaryItem[]; } -export interface BalancesScopeRequest { - /** Electronic cash balances, per currency scope. */ - balances: WalletBalance[]; - /* Summary of donations, per donau/year/currency. */ - donauSummary?: DonauSummaryItem[]; -} -export interface BalancesScopeResponse { - /** Electronic cash balance. */ - balance: WalletBalance; -} - -export const codecForBalance = (): Codec<WalletBalance> => - buildCodecForObject<WalletBalance>() - .property("scopeInfo", codecForAny()) // FIXME - .property("available", codecForAmountString()) - .property("pendingIncoming", codecForAmountString()) - .property("pendingOutgoing", codecForAmountString()) - .property("flags", codecForAny()) // FIXME - .build("Balance"); - -/** - * For terseness. - */ -export function mkAmount( - value: number, - fraction: number, - currency: string, -): AmountJson { - return { value, fraction, currency }; -} - /** * Status of a coin. */ @@ -931,48 +866,6 @@ export const codecForTalerErrorDetail = (): Codec<TalerErrorDetail> => export type ConfirmPayResult = ConfirmPayResultDone | ConfirmPayResultPending; -export const codecForConfirmPayResultPending = - (): Codec<ConfirmPayResultPending> => - buildCodecForObject<ConfirmPayResultPending>() - .property("lastError", codecOptional(codecForTalerErrorDetail())) - .property("transactionId", codecForTransactionIdStr()) - .property("type", codecForConstString(ConfirmPayResultType.Pending)) - .build("ConfirmPayResultPending"); - -export const codecForConfirmPayResultDone = (): Codec<ConfirmPayResultDone> => - buildCodecForObject<ConfirmPayResultDone>() - .property("type", codecForConstString(ConfirmPayResultType.Done)) - .property("transactionId", codecForTransactionIdStr()) - .property("contractTerms", codecForMerchantContractTermsV0()) - .build("ConfirmPayResultDone"); - -export const codecForConfirmPayResult = (): Codec<ConfirmPayResult> => - buildCodecForUnion<ConfirmPayResult>() - .discriminateOn("type") - .alternative( - ConfirmPayResultType.Pending, - codecForConfirmPayResultPending(), - ) - .alternative(ConfirmPayResultType.Done, codecForConfirmPayResultDone()) - .build("ConfirmPayResult"); - -/** - * Information about all sender wire details known to the wallet, - * as well as exchanges that accept these wire types. - */ -export interface SenderWireInfos { - /** - * Mapping from exchange base url to list of accepted - * wire types. - */ - exchangeWireTypes: { [exchangeBaseUrl: string]: string[] }; - - /** - * Sender wire information stored in the wallet. - */ - senderWires: string[]; -} - export enum InsufficientBalanceHint { /** * Merchant doesn't accept money from exchange(s) that the wallet supports. @@ -1485,13 +1378,6 @@ export const codecForPreparePayForPaivanaRequest = .property("progressToken", codecOptional(codecForString())) .build("PreparePayForPaivanaRequest"); -export const codecForPreparePayForPaivanaResult = - (): Codec<PreparePayForPaivanaResult> => - buildCodecForObject<PreparePayForPaivanaResult>() - .property("transactionId", codecForTransactionIdStr()) - .property("paivana", codecForPaivanaRedemption()) - .build("PreparePayForPaivanaResult"); - export const codecForGetPaivanaCookieRequest = (): Codec<GetPaivanaCookieRequest> => buildCodecForObject<GetPaivanaCookieRequest>() @@ -1499,12 +1385,6 @@ export const codecForGetPaivanaCookieRequest = .property("paivana", codecForPaivanaRedemption()) .build("GetPaivanaCookieRequest"); -export const codecForGetPaivanaCookieResult = - (): Codec<GetPaivanaCookieResult> => - buildCodecForObject<GetPaivanaCookieResult>() - .property("cookie", codecForString()) - .build("GetPaivanaCookieResult"); - export interface BankWithdrawDetails { status: WithdrawalOperationStatusFlag; currency: string; @@ -1526,24 +1406,6 @@ export interface AcceptWithdrawalResponse { transactionId: TransactionIdStr; } -/** - * Details about a purchase, including refund status. - */ -export interface PurchaseDetails { - contractTerms: Record<string, undefined>; - hasRefund: boolean; - totalRefundAmount: AmountJson; - totalRefundAndRefreshFees: AmountJson; -} - -export interface WalletDiagnostics { - walletManifestVersion: string; - walletManifestDisplayVersion: string; - errors: string[]; - firefoxIdbProblem: boolean; - dbOutdated: boolean; -} - export interface TalerErrorDetail { code: TalerErrorCode; when?: AbsoluteTime; @@ -1679,10 +1541,6 @@ export interface DepositInfo { walletDataHash?: string; } -export interface ExchangesShortListResponse { - exchanges: ShortExchangeListItem[]; -} - export interface ExchangesListResponse { exchanges: ExchangeListItem[]; } @@ -1793,11 +1651,6 @@ export interface TaldirLookupResponse { targetUri?: string; } -export const codecForTaldirLookupResponse = (): Codec<TaldirLookupResponse> => - buildCodecForObject<TaldirLookupResponse>() - .property("targetUri", codecOptional(codecForString())) - .build("TaldirLookupResponse"); - export interface GetMailboxResponse { mailboxConfiguration?: MailboxConfiguration; } @@ -2011,21 +1864,6 @@ export interface ExchangeGlobalFees { signature: string; } -const codecForWireFee = (): Codec<WireFee> => - buildCodecForObject<WireFee>() - .property("sig", codecForString()) - .property("wireFee", codecForAmountString()) - .property("closingFee", codecForAmountString()) - .property("startStamp", codecForTimestamp) - .property("endStamp", codecForTimestamp) - .build("codecForWireFee"); - -const codecForWireInfo = (): Codec<WireInfo> => - buildCodecForObject<WireInfo>() - .property("feesForType", codecForMap(codecForList(codecForWireFee()))) - .property("accounts", codecForList(codecForExchangeWireAccount())) - .build("codecForWireInfo"); - export interface DenominationInfo { /** * Value of one coin of the denomination. @@ -2183,10 +2021,6 @@ export interface OperationErrorInfo { error: TalerErrorDetail; } -export interface ShortExchangeListItem { - exchangeBaseUrl: string; -} - /** * Info about an exchange entry in the wallet. */ @@ -2218,16 +2052,6 @@ export interface ExchangeKeyChangeInfo { firstSeen: TalerPreciseTimestamp; } -export const codecForExchangeKeyChangeInfo = (): Codec<ExchangeKeyChangeInfo> => - buildCodecForObject<ExchangeKeyChangeInfo>() - .property("currentMasterPub", codecForString()) - .property("currentCurrency", codecForString()) - .property("supersededMasterPub", codecForString()) - .property("supersededCurrency", codecForString()) - .property("sharesDenominations", codecForBoolean()) - .property("firstSeen", codecForPreciseTimestamp) - .build("ExchangeKeyChangeInfo"); - export interface ExchangeListItem { exchangeBaseUrl: string; source?: ExchangeEntrySource; @@ -2338,62 +2162,6 @@ export interface MailboxMessageRecord { talerUri: string; } -const codecForAuditorDenomSig = (): Codec<AuditorDenomSig> => - buildCodecForObject<AuditorDenomSig>() - .property("denom_pub_h", codecForString()) - .property("auditor_sig", codecForString()) - .build("AuditorDenomSig"); - -const codecForExchangeAuditor = (): Codec<ExchangeAuditor> => - buildCodecForObject<ExchangeAuditor>() - .property("auditor_pub", codecForString()) - .property("auditor_url", codecForString()) - .property("auditor_name", codecForString()) - .property("denomination_keys", codecForList(codecForAuditorDenomSig())) - .build("codecForExchangeAuditor"); - -export const codecForFeeDescriptionPair = (): Codec<FeeDescriptionPair> => - buildCodecForObject<FeeDescriptionPair>() - .property("group", codecForString()) - .property("from", codecForAbsoluteTime) - .property("until", codecForAbsoluteTime) - .property("left", codecOptional(codecForAmountString())) - .property("right", codecOptional(codecForAmountString())) - .build("FeeDescriptionPair"); - -export const codecForFeeDescription = (): Codec<FeeDescription> => - buildCodecForObject<FeeDescription>() - .property("group", codecForString()) - .property("from", codecForAbsoluteTime) - .property("until", codecForAbsoluteTime) - .property("fee", codecOptional(codecForAmountString())) - .build("FeeDescription"); - -export const codecForFeesByOperations = (): Codec< - DenomOperationMap<FeeDescription[]> -> => - buildCodecForObject<DenomOperationMap<FeeDescription[]>>() - .property("deposit", codecForList(codecForFeeDescription())) - .property("withdraw", codecForList(codecForFeeDescription())) - .property("refresh", codecForList(codecForFeeDescription())) - .property("refund", codecForList(codecForFeeDescription())) - .build("DenomOperationMap"); - -export const codecForExchangeFullDetails = (): Codec<ExchangeFullDetails> => - buildCodecForObject<ExchangeFullDetails>() - .property("currency", codecForString()) - .property("exchangeBaseUrl", codecForCanonBaseUrl()) - .property("paytoUris", codecForList(codecForString())) - .property("auditors", codecForList(codecForExchangeAuditor())) - .property("wireInfo", codecForWireInfo()) - .property("denomFees", codecForFeesByOperations()) - .property( - "transferFees", - codecForMap(codecForList(codecForFeeDescription())), - ) - .property("globalFees", codecForList(codecForFeeDescription())) - .build("ExchangeFullDetails"); - export interface AcceptManualWithdrawalResult { /** * Transaction ID of the newly created withdrawal transaction. @@ -2657,12 +2425,6 @@ export interface GetExchangeEntryByUrlRequest { exchangeBaseUrl: string; } -export const codecForGetExchangeDetailedInfoRequest = - (): Codec<GetExchangeDetailedInfoRequest> => - buildCodecForObject<GetExchangeDetailedInfoRequest>() - .property("exchangeBaseUrl", codecForCanonBaseUrl()) - .build("GetExchangeDetailedInfoRequest"); - export interface GetExchangeDetailedInfoRequest { exchangeBaseUrl: string; } @@ -2764,16 +2526,6 @@ export const codecForDeleteExchangeRequest = (): Codec<DeleteExchangeRequest> => .property("purge", codecOptional(codecForBoolean())) .build("DeleteExchangeRequest"); -export interface ForceExchangeUpdateRequest { - exchangeBaseUrl: string; -} - -export const codecForForceExchangeUpdateRequest = - (): Codec<AddExchangeRequest> => - buildCodecForObject<AddExchangeRequest>() - .property("exchangeBaseUrl", codecOptional(codecForCanonBaseUrl())) - .build("AddExchangeRequest"); - export interface GetExchangeTosRequest { exchangeBaseUrl: string; acceptedFormat?: string[]; @@ -2937,35 +2689,6 @@ export const codecForConfirmExchangeKeyChangeRequest = .property("currentMasterPub", codecForString()) .build("ConfirmExchangeKeyChangeRequest"); -export interface ForgetExchangeTosRequest { - exchangeBaseUrl: string; -} - -export const codecForForgetExchangeTosRequest = - (): Codec<ForgetExchangeTosRequest> => - buildCodecForObject<ForgetExchangeTosRequest>() - .property("exchangeBaseUrl", codecForCanonBaseUrl()) - .build("ForgetExchangeTosRequest"); - -export interface AcceptRefundRequest { - transactionId: TransactionIdStr; -} - -export const codecForApplyRefundRequest = (): Codec<AcceptRefundRequest> => - buildCodecForObject<AcceptRefundRequest>() - .property("transactionId", codecForTransactionIdStr()) - .build("AcceptRefundRequest"); - -export interface ApplyRefundFromPurchaseIdRequest { - purchaseId: string; -} - -export const codecForApplyRefundFromPurchaseIdRequest = - (): Codec<ApplyRefundFromPurchaseIdRequest> => - buildCodecForObject<ApplyRefundFromPurchaseIdRequest>() - .property("purchaseId", codecForString()) - .build("ApplyRefundFromPurchaseIdRequest"); - export interface GetWithdrawalDetailsForUriRequest { talerWithdrawUri: string; /** @@ -3144,10 +2867,6 @@ export const codecForUnclaimPaymentRequest = (): Codec<UnclaimPaymentRequest> => export interface UnclaimPaymentResult { talerPayUri: TalerUriString; } -export const codecForUnclaimPaymentResult = (): Codec<UnclaimPaymentResult> => - buildCodecForObject<UnclaimPaymentResult>() - .property("talerPayUri", codecForTalerUriString()) - .build("UnclaimPaymentResult"); export interface CheckPayTemplateRequest { talerPayTemplateUri: string; @@ -3442,29 +3161,6 @@ export interface RefreshPlanchetInfo { exchangeWithdrawValues: ExchangeWithdrawValue; } -/** - * Strategy for loading recovery information. - */ -export enum RecoveryMergeStrategy { - /** - * Keep the local wallet root key, import and take over providers. - */ - Ours = "ours", - - /** - * Migrate to the wallet root key from the recovery information. - */ - Theirs = "theirs", -} - -/** - * Load recovery information into the wallet. - */ -export interface RecoveryLoadRequest { - recovery: BackupRecovery; - strategy?: RecoveryMergeStrategy; -} - export const codecForWithdrawTestBalance = (): Codec<WithdrawTestBalanceRequest> => buildCodecForObject<WithdrawTestBalanceRequest>() @@ -3698,10 +3394,6 @@ export interface CreateDepositGroupResponse { depositGroupId: string; } -export interface TxIdResponse { - transactionId: TransactionIdStr; -} - export interface WithdrawUriInfoResponse { operationId: string; status: WithdrawalOperationStatusFlag; @@ -3724,33 +3416,6 @@ export interface WithdrawUriInfoResponse { possibleExchanges: ExchangeListItem[]; } -export interface WalletCurrencyInfo { - trustedAuditors: { - currency: string; - auditorPub: string; - auditorBaseUrl: string; - }[]; - trustedExchanges: { - currency: string; - exchangeMasterPub: string; - exchangeBaseUrl: string; - }[]; -} - -export interface TestingListTasksForTransactionRequest { - transactionId: TransactionIdStr; -} - -export interface TestingListTasksForTransactionsResponse { - taskIdList: string[]; -} - -export const codecForTestingListTasksForTransactionRequest = - (): Codec<TestingListTasksForTransactionRequest> => - buildCodecForObject<TestingListTasksForTransactionRequest>() - .property("transactionId", codecForTransactionIdStr()) - .build("TestingListTasksForTransactionRequest"); - export interface DeleteTransactionRequest { transactionId: TransactionIdStr; } @@ -3771,20 +3436,6 @@ export const codecForRetryTransactionRequest = .property("transactionId", codecForTransactionIdStr()) .build("RetryTransactionRequest"); -export interface WithdrawFakebankRequest { - amount: AmountString; - exchange: string; - bank: string; -} - -export const codecForWithdrawFakebankRequest = - (): Codec<WithdrawFakebankRequest> => - buildCodecForObject<WithdrawFakebankRequest>() - .property("amount", codecForAmountString()) - .property("bank", codecForString()) - .property("exchange", codecForString()) - .build("WithdrawFakebankRequest"); - export interface ActiveTask { taskId: string; transaction?: TransactionIdStr | undefined; @@ -3798,21 +3449,6 @@ export interface GetActiveTasksResponse { tasks: ActiveTask[]; } -export const codecForActiveTask = (): Codec<ActiveTask> => - buildCodecForObject<ActiveTask>() - .property("taskId", codecForString()) - .property("transaction", codecOptional(codecForTransactionIdStr())) - .property("retryCounter", codecOptional(codecForNumber())) - .property("firstTry", codecOptional(codecForAbsoluteTime)) - .property("nextTry", codecOptional(codecForAbsoluteTime)) - .property("lastError", codecOptional(codecForTalerErrorDetail())) - .build("ActiveTask"); - -export const codecForGetActiveTasks = (): Codec<GetActiveTasksResponse> => - buildCodecForObject<GetActiveTasksResponse>() - .property("tasks", codecForList(codecForActiveTask())) - .build("GetActiveTasks"); - export interface ImportDbRequest { dump?: any; @@ -3890,20 +3526,6 @@ export interface PayCoinSelection { totalDepositFees: AmountString; } -export interface ProspectivePayCoinSelection { - prospectiveCoins: SelectedProspectiveCoin[]; - - /** - * How much of the wire fees is the customer paying? - */ - customerWireFees: AmountString; - - /** - * How much of the deposit fees is the customer paying? - */ - customerDepositFees: AmountString; -} - export interface CheckPeerPushDebitRequest { /** * Preferred exchange to use for the p2p payment. @@ -4234,18 +3856,8 @@ export interface ValidateIbanResponse { valid: boolean; } -export const codecForValidateIbanResponse = (): Codec<ValidateIbanResponse> => - buildCodecForObject<ValidateIbanResponse>() - .property("valid", codecForBoolean()) - .build("ValidateIbanResponse"); - export type TransactionStateFilter = "nonfinal"; -export interface TransactionRecordFilter { - onlyState?: TransactionStateFilter; - onlyCurrency?: string; -} - export interface TestingSetTimetravelRequest { offsetMs: number; } diff --git a/packages/taler-wallet-core/src/balance.ts b/packages/taler-wallet-core/src/balance.ts @@ -1002,19 +1002,6 @@ export interface PaymentRestrictionsForBalance { depositPaytoUri: string | undefined; } -export interface AcceptableExchanges { - /** - * Exchanges accepted by the merchant, but wire method might not match. - */ - acceptableExchanges: string[]; - - /** - * Exchanges accepted by the merchant, including a matching - * wire method, i.e. the merchant can deposit coins there. - */ - depositableExchanges: string[]; -} - export interface PaymentBalanceDetails { /** * Balance of type "available" (see balance.ts for definition). diff --git a/packages/taler-wallet-core/src/common.ts b/packages/taler-wallet-core/src/common.ts @@ -41,7 +41,6 @@ import { TalerPreciseTimestamp, TalerPreparedTransferHttpClient, TalerProtocolTimestamp, - TombstoneIdStr, Transaction, TransactionIdStr, TransactionMajorState, @@ -62,7 +61,6 @@ import { } from "@gnu-taler/taler-util"; import { HttpRequestOptions, HttpResponse } from "@gnu-taler/taler-util/http"; import { - DbPreciseTimestamp, ExchangeEntryDbRecordStatus, ExchangeEntryDbUpdateStatus, WalletCoin, @@ -345,20 +343,6 @@ export async function spendTokens( } } -export enum TombstoneTag { - DeleteWithdrawalGroup = "delete-withdrawal-group", - DeleteReserve = "delete-reserve", - DeletePayment = "delete-payment", - DeleteReward = "delete-reward", - DeleteRefreshGroup = "delete-refresh-group", - DeleteDepositGroup = "delete-deposit-group", - DeleteRefund = "delete-refund", - DeletePeerPullDebit = "delete-peer-pull-debit", - DeletePeerPushDebit = "delete-peer-push-debit", - DeletePeerPullCredit = "delete-peer-pull-credit", - DeletePeerPushCredit = "delete-peer-push-credit", -} - export function getExchangeTosStatusFromRecord( exchange: WalletExchangeEntry, ): ExchangeTosStatus { @@ -424,49 +408,6 @@ export function getExchangeState(r: WalletExchangeEntry): ExchangeEntryState { }; } -export type ParsedTombstone = - | { - tag: TombstoneTag.DeleteWithdrawalGroup; - withdrawalGroupId: string; - } - | { tag: TombstoneTag.DeleteRefund; refundGroupId: string } - | { tag: TombstoneTag.DeleteReserve; reservePub: string } - | { tag: TombstoneTag.DeleteRefreshGroup; refreshGroupId: string } - | { tag: TombstoneTag.DeleteReward; walletTipId: string } - | { tag: TombstoneTag.DeletePayment; proposalId: string }; - -export function constructTombstone(p: ParsedTombstone): TombstoneIdStr { - switch (p.tag) { - case TombstoneTag.DeleteWithdrawalGroup: - return `tmb:${p.tag}:${p.withdrawalGroupId}` as TombstoneIdStr; - case TombstoneTag.DeleteRefund: - return `tmb:${p.tag}:${p.refundGroupId}` as TombstoneIdStr; - case TombstoneTag.DeleteReserve: - return `tmb:${p.tag}:${p.reservePub}` as TombstoneIdStr; - case TombstoneTag.DeletePayment: - return `tmb:${p.tag}:${p.proposalId}` as TombstoneIdStr; - case TombstoneTag.DeleteRefreshGroup: - return `tmb:${p.tag}:${p.refreshGroupId}` as TombstoneIdStr; - case TombstoneTag.DeleteReward: - return `tmb:${p.tag}:${p.walletTipId}` as TombstoneIdStr; - default: - assertUnreachable(p); - } -} - -/** - * Uniform interface for a particular wallet transaction. - */ -export interface TransactionManager { - get taskId(): TaskIdStr; - get transactionId(): TransactionIdStr; - fail(): Promise<void>; - abort(): Promise<void>; - suspend(): Promise<void>; - resume(): Promise<void>; - process(): Promise<TaskRunResult>; -} - export enum TaskRunResultType { Finished = "finished", Backoff = "backoff", @@ -667,27 +608,6 @@ function updateTimeout( r.nextRetry = timestampPreciseToDb(TalerPreciseTimestamp.fromMilliseconds(t)); } -export function computeDbBackoff(retryCounter: number): DbPreciseTimestamp { - const now = AbsoluteTime.now(); - if (now.t_ms === "never") { - throw Error("assertion failed"); - } - const p = defaultRetryPolicy; - if (p.backoffDelta.d_ms === "forever") { - throw Error("assertion failed"); - } - - const nextIncrement = - p.backoffDelta.d_ms * Math.pow(p.backoffBase, retryCounter); - - const t = - now.t_ms + - (p.maxTimeout.d_ms === "forever" - ? nextIncrement - : Math.min(p.maxTimeout.d_ms, nextIncrement)); - return timestampPreciseToDb(TalerPreciseTimestamp.fromMilliseconds(t)); -} - export namespace DbRetryInfo { export function reset(p: RetryPolicy = defaultRetryPolicy): DbRetryInfo { const now = TalerPreciseTimestamp.now(); diff --git a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts @@ -102,7 +102,6 @@ import { TalerProtocolTimestamp, TalerSignaturePurpose, timestampRoundedToBuffer, - toHexString, TokenEnvelope, TokenIssueBlindSig, UnblindedDenominationSignature, @@ -153,17 +152,6 @@ import { const logger = new Logger("cryptoImplementation.ts"); -let debugDumpSigs = false; - -/** - * Enable dumping of signature blobs to stderr. - * - * Global option, must only be used for debugging. - */ -export function setDebugDumpSigs(b: boolean) { - debugDumpSigs = b; -} - async function createRefreshCoinEnvelope( tci: TalerCryptoInterfaceR, denomPub: DenominationPubKey, @@ -2114,13 +2102,6 @@ export const nativeCryptoR: TalerCryptoInterfaceR = { priv: depositInfo.coinPriv, }); - if (debugDumpSigs) { - logger.info( - `Dumping deposit signature for ct=${depositInfo.contractTermsHash}`, - ); - logger.info(`Deposit signature: ${toHexString(d)}`); - } - const s: CoinDepositPermission = { coin_pub: depositInfo.coinPub, coin_sig: coinSigRes.sig, @@ -2201,19 +2182,6 @@ export const nativeCryptoR: TalerCryptoInterfaceR = { sessionHc.update(decodeCrock(meltCoinPub)); sessionHc.update(bufferFromAmount(valueWithFee)); - if (debugDumpSigs) { - logger.info(`hashing blinding seed: ${toHexString(blindingSeed)}`); - logger.info( - `hashing session seed: ${toHexString(decodeCrock(sessionPublicSeed))}`, - ); - logger.info( - `hashing melt coin pub: ${toHexString(decodeCrock(meltCoinPub))}`, - ); - logger.info( - `hashing amount: ${toHexString(bufferFromAmount(valueWithFee))}`, - ); - } - for (let i = 0; i < kappa; i++) { const planchets: RefreshPlanchetInfo[] = []; const nonce = noncesBytes.slice(i * 64, i * 64 + 64); @@ -2295,9 +2263,6 @@ export const nativeCryptoR: TalerCryptoInterfaceR = { } const planchetsHash = planchetsHc.finish(); - if (debugDumpSigs) { - logger.info(`planchets hash ${i}: ${toHexString(planchetsHash)}`); - } sessionHc.update(planchetsHash); planchetsForGammas.push(planchets); @@ -2323,13 +2288,6 @@ export const nativeCryptoR: TalerCryptoInterfaceR = { .put(bufferFromAmount(feeRefresh)) .build(); - if (debugDumpSigs) { - logger.info(`melt signature blob:`); - logger.info(toHexString(confirmData)); - logger.info(`valueWithFee: ${Amounts.stringify(valueWithFee)}`); - logger.info(`meltFee: ${Amounts.stringify(feeRefresh)}`); - } - const confirmSigResp = await tci.eddsaSign(tci, { msg: encodeCrock(confirmData), priv: meltCoinPriv, diff --git a/packages/taler-wallet-core/src/db/indexeddb/database.ts b/packages/taler-wallet-core/src/db/indexeddb/database.ts @@ -549,23 +549,3 @@ export async function retireTalerDatabaseGeneration( ): Promise<void> { await cleanupGeneration(idbFactory, name, RETIRED_DB_CONFIG_KEY, currentName); } - -export async function deleteTalerDatabase( - idbFactory: IDBFactory, -): Promise<void> { - const state = await readMainDbState(idbFactory, false); - const names = new Set([ - TALER_WALLET_MAIN_DB_NAME, - state.current, - state.pending, - state.retired, - ]); - for (const name of names) { - if (name && !(await tryDeleteDatabase(idbFactory, name))) { - throw Error(`deletion of wallet database ${name} is blocked`); - } - } - if (!(await tryDeleteDatabase(idbFactory, TALER_WALLET_META_DB_NAME))) { - throw Error("deletion of wallet metadata database is blocked"); - } -} diff --git a/packages/taler-wallet-core/src/db/indexeddb/schema.ts b/packages/taler-wallet-core/src/db/indexeddb/schema.ts @@ -95,7 +95,6 @@ import { describeStore, describeStoreV2, StoreNames, - StoreWithIndexes, } from "../query.js"; /** * This file contains the database schema of the Taler wallet together @@ -171,9 +170,6 @@ export const TALER_WALLET_DB_GENERATION_PREFIX = `${TALER_WALLET_MAIN_DB_NAME}-g */ export const WALLET_DB_MINOR_VERSION = 34; -// FIXME: Should these be numeric codes? -export type KycUserType = "individual" | "business"; - export interface BankWithdrawUriRecord { /** * The withdraw URI we got from the bank. @@ -439,16 +435,6 @@ export interface PeerPullPaymentIncomingRecord { coinSel?: PeerPullPaymentCoinSelection; } -export interface DbExchangeHandle { - url: string; - exchangeMasterPub: string; -} - -export interface DbAuditorHandle { - url: string; - auditorPub: string; -} - export function passthroughCodec<T>(): Codec<T> { return codecForAny(); } @@ -1286,86 +1272,3 @@ export const walletMetadataStore = { {}, ), }; - -/** - * Compile-time proof that every IndexedDB record type can actually be stored. - * - * The store definitions below use the DAL's `Wallet<Name>` types directly as - * their record types, so a change made for the native sqlite backend changes - * what IndexedDB persists. That is fine while the types stay - * structured-clone friendly, and fatal the moment one does not: the - * serialiser these values pass through on their way to storage - * (structuredEncapsulate in idb-bridge) handles arrays, dates, plain objects, - * bigint, boolean, number and string, and throws on anything else. Typed - * arrays included -- IndexedDB here cannot store binary at all. - * - * Without this, giving a record field a Uint8Array type -- the direction the - * native backend wants to go, to stop encoding keys as Crockford base32 -- - * would compile cleanly and fail at runtime, on write, in production. - * - * The record types are derived from the store map rather than listed, so a - * new store is covered without anyone remembering to add it here. - * - * When this stops compiling: do not widen it. It means a stored type has - * gained a field IndexedDB cannot persist -- typically a Uint8Array, which - * structuredEncapsulate cannot represent. The fix is to give the IndexedDB - * store its own record type holding whatever it can persist, and convert at - * the DAL boundary, not to relax the check. - */ -type Persistable<T> = T extends ArrayBufferView | ArrayBuffer - ? never - : T extends (...args: any[]) => any - ? never - : // Primitives are checked before objects on purpose: the branded types - // used throughout the records (DbPreciseTimestamp is number & {...}, - // AmountString is string & {...}) are intersections that satisfy - // `extends object`, and mapping over one turns a number into an object - // type. That flagged perfectly persistable records. - T extends string | number | boolean | bigint | null | undefined - ? T - : T extends Date - ? T - : T extends Array<infer U> - ? Array<Persistable<U>> - : T extends object - ? { [K in keyof T]: Persistable<T[K]> } - : T; - -/** - * The tuple wrappers stop the outer conditional from distributing over a - * union of record types, which would let a single unpersistable member hide - * behind its persistable siblings. - */ -type IsPersistable<T> = [T] extends [Persistable<T>] ? true : false; - -type AssertTrue<T extends true> = T; - -type RecordTypeOf<S> = - S extends StoreWithIndexes<any, infer R, any> ? R : never; - -type StoreMapV1 = typeof WalletIndexedDbStoresV1; - -/** - * The names of stores whose record type cannot be persisted, or never. - * - * Checked per store rather than over the union of all record types: two - * obsolete stores are typed `any`, and `any` in a union makes every other - * member assignable to it, which made an earlier version of this check pass - * a record type containing a Uint8Array. A vacuous guard is worse than no - * guard, because it is trusted. - */ -type UnpersistableStores = { - [K in keyof StoreMapV1]: IsPersistable< - RecordTypeOf<StoreMapV1[K]> - > extends true - ? never - : K; -}[keyof StoreMapV1]; - -/** - * The assertion itself. Unused at runtime; its only job is to fail the build, - * naming the offending store in the error. - */ -export type _AllIndexedDbRecordsArePersistable = AssertTrue< - [UnpersistableStores] extends [never] ? true : UnpersistableStores ->; diff --git a/packages/taler-wallet-core/src/db/sqlite/schema.ts b/packages/taler-wallet-core/src/db/sqlite/schema.ts @@ -292,11 +292,6 @@ export const BLOB_COLUMNS: Readonly<Record<string, readonly string[]>> = { ], }; -/** True when the column is stored as a BLOB. */ -export function isBlobColumn(table: string, column: string): boolean { - return BLOB_COLUMNS[table]?.includes(column) ?? false; -} - export const SQLITE_BASELINE_SCHEMA = ` CREATE TABLE IF NOT EXISTS schema_migrations ( version INTEGER PRIMARY KEY, diff --git a/packages/taler-wallet-core/src/db/sqlite/transaction.ts b/packages/taler-wallet-core/src/db/sqlite/transaction.ts @@ -19,9 +19,8 @@ * possible: no cursors, no key ranges, compound keys as separate parameters, * generated ids returned from upserts. * - * Work in progress. Methods that are not implemented yet throw - * {@link NotImplementedError} rather than being silently wrong; the - * conformance suite is the checklist. + * Work in progress. The conformance suite is the checklist for methods that + * are not implemented yet. */ import { @@ -126,12 +125,6 @@ import { const logger = new Logger("db/sqlite/transaction.ts"); -export class NotImplementedError extends Error { - constructor(method: string) { - super(`sqlite DAL: ${method} is not implemented yet`); - } -} - /** Encode an optional boolean the way sqlite wants it. */ function boolToDb(b: boolean | undefined): number | null { if (b === undefined) return null; diff --git a/packages/taler-wallet-core/src/db/timestamps.ts b/packages/taler-wallet-core/src/db/timestamps.ts @@ -93,15 +93,3 @@ export function timestampAbsoluteFromDb( } return AbsoluteTime.fromMilliseconds(Math.floor(stamp / 1000)); } - -export function timestampOptionalAbsoluteFromDb( - stamp: DbProtocolTimestamp | DbPreciseTimestamp | undefined, -): AbsoluteTime | undefined { - if (stamp == null) { - return undefined; - } - if (stamp >= DB_TIMESTAMP_FOREVER) { - return AbsoluteTime.never(); - } - return AbsoluteTime.fromMilliseconds(Math.floor(stamp / 1000)); -} diff --git a/packages/taler-wallet-core/src/denominations.ts b/packages/taler-wallet-core/src/denominations.ts @@ -409,22 +409,6 @@ export function isCandidateWithdrawableDenomRec( return started && stillOkay && !d.isRevoked && d.isOffered && !d.isLost; } -export function isCandidateWithdrawableDenomInfo(d: DenominationInfo): boolean { - const now = AbsoluteTime.now(); - const start = AbsoluteTime.fromProtocolTimestamp(d.stampStart); - const started = AbsoluteTime.cmp(now, start) >= 0; - const withdrawExpire = AbsoluteTime.fromProtocolTimestamp( - d.stampExpireWithdraw, - ); - const lastPossibleWithdraw = AbsoluteTime.subtractDuraction( - withdrawExpire, - Duration.fromSpec({ minutes: 5 }), - ); - const remaining = Duration.getRemaining(lastPossibleWithdraw, now); - const stillOkay = remaining.d_ms !== 0; - return started && stillOkay && d.isOffered && !d.isLost; -} - export async function isValidDenomRecord( wex: WalletExecutionContext, exchangeMasterPub: string, diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts @@ -4533,32 +4533,6 @@ export async function getExchangeResources( return res; } -/** - * Find the currently applicable wire fee for an exchange. - */ -export async function getExchangeWireFee( - wex: WalletExecutionContext, - wireType: string, - baseUrl: string, - time: TalerProtocolTimestamp, -): Promise<WireFee> { - const exchangeDetails = await wex.runWalletDbTx(async (tx) => { - const ex = await tx.getExchange(baseUrl); - if (!ex || !ex.detailsPointer) return undefined; - return await tx.getExchangeDetailsByPointer( - baseUrl, - ex.detailsPointer.currency, - ex.detailsPointer.masterPublicKey, - ); - }); - - if (!exchangeDetails) { - throw Error(`exchange missing: ${baseUrl}`); - } - - return findExchangeWireFee(exchangeDetails, wireType, time); -} - /** Find the applicable wire fee in already-loaded exchange details. */ export function findExchangeWireFee( exchangeDetails: WalletExchangeDetails, diff --git a/packages/taler-wallet-core/src/host-common.ts b/packages/taler-wallet-core/src/host-common.ts @@ -85,19 +85,6 @@ export async function acquireSqliteWalletDbOwnership( } /** - * Generate a random alphanumeric ID. Does *not* use cryptographically - * secure randomness. - */ -export function makeTempfileId(length: number): string { - let result = ""; - const characters = "abcdefghijklmnopqrstuvwxyz0123456789"; - for (let i = 0; i < length; i++) { - result += characters.charAt(Math.floor(Math.random() * characters.length)); - } - return result; -} - -/** * Get the underlying sqlite3 DB filename * from the storage path specified by the wallet-core client. */ diff --git a/packages/taler-wallet-core/src/host.ts b/packages/taler-wallet-core/src/host.ts @@ -32,13 +32,3 @@ export async function createNativeWalletHost2( }> { return hostImpl.createNativeWalletHost2(args); } - -/** - * Get a wallet instance. - */ -export async function createNativeWalletHost( - args: DefaultNodeWalletArgs = {}, -): Promise<Wallet> { - const res = await hostImpl.createNativeWalletHost2(args); - return res.wallet; -} diff --git a/packages/taler-wallet-core/src/index.ts b/packages/taler-wallet-core/src/index.ts @@ -39,7 +39,6 @@ export { createPairTimeline } from "./denominations.js"; // FIXME: Should these really be exported?! export { WithdrawalGroupStatus } from "./db/records.js"; -export { deleteTalerDatabase } from "./db/indexeddb/database.js"; export { exportDb, importDb } from "./db/indexeddb/dump.js"; export { TALER_WALLET_MAIN_DB_NAME, diff --git a/packages/taler-wallet-core/src/instructedAmountConversion.ts b/packages/taler-wallet-core/src/instructedAmountConversion.ts @@ -419,31 +419,6 @@ export function convertDepositAmountForAvailableCoins( return result; } -export async function convertWithdrawalAmount( - wex: WalletExecutionContext, - req: ConvertAmountRequest, -): Promise<AmountResponse> { - const amount = Amounts.parseOrThrow(req.amount); - - const denoms = await getAvailableCoins( - wex, - TransactionType.Withdrawal, - amount.currency, - {}, - ); - - const result = convertWithdrawalAmountFromAvailableCoins( - denoms, - amount, - req.type, - ); - - return { - effectiveAmount: Amounts.stringify(result.effective), - rawAmount: Amounts.stringify(result.raw), - }; -} - export function convertWithdrawalAmountFromAvailableCoins( denoms: AvailableCoins, amount: AmountJson, diff --git a/packages/taler-wallet-core/src/observable-wrappers.ts b/packages/taler-wallet-core/src/observable-wrappers.ts @@ -21,9 +21,7 @@ /** * Imports. */ -import { IDBDatabase } from "@gnu-taler/idb-bridge"; import { - getErrorDetailFromException, ObservabilityContext, ObservabilityEventType, performanceDelta, @@ -31,12 +29,6 @@ import { } from "@gnu-taler/taler-util"; import { TaskIdStr } from "./common.js"; import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js"; -import { - DbAccess, - DbReadWriteTransaction, - StoreMap, - StoreNames, -} from "./db/query.js"; import { TaskScheduler } from "./shepherd.js"; /** @@ -128,56 +120,6 @@ export function getCallerInfo(up: number = 2): string { return identifies.slice(up, up + 2).join("/"); } -export class ObservableDbAccess< - Stores extends StoreMap, -> implements DbAccess<Stores> { - constructor( - private impl: DbAccess<Stores>, - private oc: ObservabilityContext, - ) {} - idbHandle(): IDBDatabase { - return this.impl.idbHandle(); - } - - async runAllStoresReadWriteTx<T>( - options: { - label?: string; - }, - txf: ( - tx: DbReadWriteTransaction<Stores, StoreNames<Stores>[]>, - ) => Promise<T>, - ): Promise<T> { - const location = getCallerInfo(); - this.oc.observe({ - type: ObservabilityEventType.DbQueryStart, - name: "<unknown>", - location, - }); - const start = performanceNow(); - try { - const ret = await this.impl.runAllStoresReadWriteTx(options, txf); - const end = performanceNow(); - this.oc.observe({ - type: ObservabilityEventType.DbQueryFinishSuccess, - name: "<unknown>", - location, - durationMs: performanceDelta(start, end), - }); - return ret; - } catch (e) { - const end = performanceNow(); - this.oc.observe({ - type: ObservabilityEventType.DbQueryFinishError, - name: "<unknown>", - location, - error: getErrorDetailFromException(e), - durationMs: performanceDelta(start, end), - }); - throw e; - } - } -} - export function observeTalerCrypto( impl: TalerCryptoInterface, oc: ObservabilityContext, diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts @@ -4296,20 +4296,6 @@ async function processPurchasePay( return TaskRunResult.progress(); } -export async function validateAndStoreToken( - wex: WalletExecutionContext, - slate: WalletSlate, - blindedEv: SignedTokenEnvelope, -): Promise<void> { - const token = await validateToken(wex, slate, blindedEv); - - // insert token and delete slate - await wex.runWalletDbTx(async (tx) => { - await tx.upsertToken(token); - await tx.deleteSlate(slate.tokenUsePub); - }); -} - export async function validateToken( wex: WalletExecutionContext, slate: WalletSlate, @@ -4407,37 +4393,6 @@ export async function generateTokenSigs( return sigs; } -export async function cleanupUsedTokens( - wex: WalletExecutionContext, - tokenPubs: string[], -): Promise<void> { - await wex.runWalletDbTx(async (tx) => { - for (const pub of tokenPubs) { - logger.trace(`cleaning up used token ${pub}`); - await tx.deleteToken(pub); - } - }); -} - -export async function refuseProposal( - wex: WalletExecutionContext, - proposalId: string, -): Promise<void> { - const ctx = new PayMerchantTransactionContext(wex, proposalId); - await wex.runWalletDbTx(async (tx) => { - const [proposal, h] = await ctx.getRecordHandle(tx); - switch (proposal?.purchaseStatus) { - case PurchaseStatus.DialogProposed: - case PurchaseStatus.DialogShared: - break; - default: - return; - } - proposal.purchaseStatus = PurchaseStatus.AbortedProposalRefused; - await h.update(proposal, "refuse-proposal"); - }); -} - const transitionSuspend: { [x in PurchaseStatus]?: { next: PurchaseStatus | undefined; diff --git a/packages/taler-wallet-core/src/refresh.ts b/packages/taler-wallet-core/src/refresh.ts @@ -80,7 +80,6 @@ import { } from "@gnu-taler/taler-util/http"; import { constructTaskIdentifier, - genericWaitForState, getGenericRecordHandle, makeCoinsVisible, PendingTaskType, @@ -349,17 +348,6 @@ export class RefreshTransactionContext implements TransactionContext { } } -export async function getTotalRefreshCost( - wex: WalletExecutionContext, - tx: WalletDbTransaction, - refreshedDenom: DenominationInfo, - amountLeft: AmountJson, -): Promise<AmountJson> { - return ( - await getTotalRefreshCosts(wex, tx, [{ refreshedDenom, amountLeft }]) - )[0]; -} - function refreshCostCacheKey( refreshedDenom: DenominationInfo, amountLeft: AmountJson, @@ -2293,46 +2281,3 @@ export async function forceRefresh( refreshGroupId: res.refreshGroupId, }; } - -/** - * Wait until a refresh operation is final. - */ -export async function waitRefreshFinal( - wex: WalletExecutionContext, - refreshGroupId: string, -): Promise<void> { - const ctx = new RefreshTransactionContext(wex, refreshGroupId); - wex.taskScheduler.startShepherdTask(ctx.taskId); - - await genericWaitForState(wex, { - async checkState(): Promise<boolean> { - // Check if refresh is final - const res = await ctx.wex.runWalletDbTx(async (tx) => { - return { - rg: await tx.getRefreshGroup(ctx.refreshGroupId), - }; - }); - const { rg } = res; - if (!rg) { - // Must've been deleted, we consider that final. - return true; - } - switch (rg.operationStatus) { - case RefreshOperationStatus.Failed: - case RefreshOperationStatus.Finished: - // Transaction is final - return true; - case RefreshOperationStatus.Pending: - case RefreshOperationStatus.Suspended: - break; - } - return false; - }, - filterNotification(notif): boolean { - return ( - notif.type === NotificationType.TransactionStateTransition && - notif.transactionId === ctx.transactionId - ); - }, - }); -} diff --git a/packages/taler-wallet-core/src/tokenSelection.ts b/packages/taler-wallet-core/src/tokenSelection.ts @@ -33,7 +33,6 @@ import { } from "@gnu-taler/taler-util"; import { timestampProtocolFromDb, WalletToken } from "./db/records.js"; import { WalletDbTransaction } from "./db/transaction.js"; -import { WalletExecutionContext } from "./wallet.js"; const logger = new Logger("tokenSelection.ts"); @@ -53,11 +52,6 @@ export interface SelectPayTokensRequest { }; } -export interface SelectPayTokensAllChoicesRequest { - proposalId: string; - contractTerms: MerchantContractTermsV1; -} - export type SelectPayTokensResult = | { type: "failure"; @@ -247,15 +241,6 @@ export async function selectPayTokensInTx( ); } -export async function selectPayTokens( - wex: WalletExecutionContext, - req: SelectPayTokensRequest, -): Promise<SelectPayTokensResult> { - return await wex.runWalletDbTx(async (tx) => { - return selectPayTokensInTx(tx, req); - }); -} - export function selectTokenCandidates( inputTokens: { [slug: string]: { diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts @@ -379,7 +379,6 @@ export function walletMerchantClient( } export const EXCHANGE_COINS_LOCK = "exchange-coins-lock"; -export const EXCHANGE_RESERVES_LOCK = "exchange-reserves-lock"; export type NotificationListener = (n: WalletNotification) => void; @@ -1165,15 +1164,6 @@ export function applyRunConfigDefaults( export type HttpFactory = (config: WalletRunConfig) => HttpRequestLibrary; /** - * How a host hands its database to the wallet. - * - * Was an interface of its own describing an IndexedDB factory plus an - * optional native handle; the host now opens exactly one backend and passes - * the handle for it, so there is nothing left to describe separately. - */ -export type WalletDatabaseImplementation = WalletDbHandle; - -/** * Public handle to a running wallet. */ export class Wallet { diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts @@ -3399,34 +3399,6 @@ export function getReserveRequestTimeout(r: WalletWithdrawalGroup): Duration { return { d_ms: 60000 }; } -export function getBankStatusUrl(talerWithdrawUri: string): URL { - const uriResult = Result.orUndefined( - TalerUris.parseRestricted(talerWithdrawUri, TalerUriAction.Withdraw), - ); - if (!uriResult) { - throw Error(`can't parse withdrawal URL ${talerWithdrawUri}`); - } - const url = new URL( - `withdrawal-operation/${uriResult.withdrawalOperationId}`, - uriResult.bankIntegrationApiBaseUrl, - ); - return url; -} - -export function getBankAbortUrl(talerWithdrawUri: string): URL { - const uriResult = Result.orUndefined( - TalerUris.parseRestricted(talerWithdrawUri, TalerUriAction.Withdraw), - ); - if (!uriResult) { - throw Error(`can't parse withdrawal URL ${talerWithdrawUri}`); - } - const url = new URL( - `withdrawal-operation/${uriResult.withdrawalOperationId}/abort`, - uriResult.bankIntegrationApiBaseUrl, - ); - return url; -} - async function registerReserveWithBank( wex: WalletExecutionContext, withdrawalGroupId: string, diff --git a/packages/wallet-webui/src/stores/ui.ts b/packages/wallet-webui/src/stores/ui.ts @@ -1,7 +1,6 @@ import { signal } from "@preact/signals"; import type { ConnectionStatus } from "../api/contracts.js"; -export const navigationOpen = signal(false); export const connectionStatus = signal<ConnectionStatus>({ state: "connecting", }); diff --git a/packages/wallet-webui/src/testing/fakes.ts b/packages/wallet-webui/src/testing/fakes.ts @@ -1,25 +0,0 @@ -import type { WalletNotification } from "@gnu-taler/taler-util"; -import type { ConnectionStatus, WalletConnection } from "../api/contracts.js"; - -export function makeFakeConnection( - client: WalletConnection["client"], -): WalletConnection { - const notifications = new Set<(n: WalletNotification) => void>(); - const statuses = new Set<(s: ConnectionStatus) => void>(); - return { - client, - subscribeNotifications(listener) { - notifications.add(listener); - return () => notifications.delete(listener); - }, - subscribeStatus(listener) { - statuses.add(listener); - listener({ state: "connected" }); - return () => statuses.delete(listener); - }, - close() { - notifications.clear(); - statuses.clear(); - }, - }; -} diff --git a/packages/web-util/build.mjs b/packages/web-util/build.mjs @@ -134,8 +134,6 @@ const buildConfigNode = { const buildConfigBrowser = { ...buildConfigBase, entryPoints: [ - "src/tests/mock.ts", - "src/tests/swr.ts", "src/index.browser.ts", "src/live-reload-ws.ts", "src/live-reload-poll.ts", diff --git a/packages/web-util/src/forms/fields/InputDrilldown.tsx b/packages/web-util/src/forms/fields/InputDrilldown.tsx @@ -5,11 +5,6 @@ import { useTranslationContext } from "../../context/translation.js"; import { resolveFieldHandler, UIFormProps } from "../FormProvider.js"; import { InputSelectOne } from "./InputSelectOne.js"; -export interface ChoiceH<V> { - label: TranslatedString; - value: V; -} - export function InputDrilldown( props: { choices?: any; diff --git a/packages/web-util/src/hooks/index.ts b/packages/web-util/src/hooks/index.ts @@ -25,7 +25,6 @@ export { StorageState, useLocalStorage, } from "./useLocalStorage.js"; -export { useMemoryStorage } from "./useMemoryStorage.js"; export * from "./useNotifications.js"; export * from "./useAsyncAction.js"; export * from "./useNotifiedOperation.js"; diff --git a/packages/web-util/src/hooks/useMemoryStorage.ts b/packages/web-util/src/hooks/useMemoryStorage.ts @@ -1,71 +0,0 @@ -/* - This file is part of GNU Anastasis - (C) 2021-2022 Anastasis SARL - - GNU Anastasis is free software; you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Anastasis 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - GNU Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { useEffect, useState } from "preact/hooks"; -import { ObservableMap, memoryMap } from "../utils/observable.js"; -import { StorageState } from "./useLocalStorage.js"; - -const storage: ObservableMap<string, any> = memoryMap<any>(); - -//with initial value -export function useMemoryStorage<Type = string>( - key: string, - defaultValue: Type, -): Required<StorageState<Type>>; -//with initial value -export function useMemoryStorage<Type = string>( - key: string, -): StorageState<Type>; -// impl -export function useMemoryStorage<Type = string>( - key: string, - defaultValue?: Type, -): StorageState<Type> { - const [storedValue, setStoredValue] = useState<Type | undefined>( - (): Type | undefined => { - const prev = storage.get(key); - return prev === undefined ? defaultValue : prev; - }, - ); - - useEffect(() => { - return storage.onUpdate(key, () => { - const newValue = storage.get(key); - setStoredValue(newValue === undefined ? defaultValue : newValue); - }); - }, [key]); - - const setValue = (value?: Type): void => { - if (value === undefined) { - storage.delete(key); - } else { - storage.set(key, value); - } - }; - - return { - value: storedValue, - update: setValue, - reset: () => { - setValue(defaultValue); - }, - }; -} diff --git a/packages/web-util/src/index.testing.ts b/packages/web-util/src/index.testing.ts @@ -1,3 +1 @@ export * from "./tests/hook.js"; -export * from "./tests/swr.js"; -export * from "./tests/mock.js"; diff --git a/packages/web-util/src/tests/mock.ts b/packages/web-util/src/tests/mock.ts @@ -1,493 +0,0 @@ -/* - 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 { Logger } from "@gnu-taler/taler-util"; - -type HttpMethod = - | "get" - | "GET" - | "delete" - | "DELETE" - | "head" - | "HEAD" - | "options" - | "OPTIONS" - | "post" - | "POST" - | "put" - | "PUT" - | "patch" - | "PATCH" - | "purge" - | "PURGE" - | "link" - | "LINK" - | "unlink" - | "UNLINK"; - -/** - * @deprecated do not use it, it will be removed - */ -export type Query<Req, Res> = { - method: HttpMethod; - url: string; - code?: number; -}; - -type ExpectationValues = { - query: Query<any, any>; - auth?: string; - params?: { - request?: object; - qparam?: Record<string, string>; - response?: object; - }; -}; - -type TestValues = { - currentExpectedQuery: ExpectationValues | undefined; - lastQuery: ExpectationValues | undefined; -}; - -const logger = new Logger("testing/mock.ts"); - -type MockedResponse = { - queryMade: ExpectationValues; - expectedQuery?: ExpectationValues; -}; - -/** - * @deprecated do not use it, it will be removed - */ -export abstract class MockEnvironment { - expectations: Array<ExpectationValues> = []; - queriesMade: Array<ExpectationValues> = []; - index = 0; - - debug: boolean; - constructor(debug: boolean) { - this.debug = debug; - this.saveRequestAndGetMockedResponse.bind(this); - } - - public addRequestExpectation< - RequestType extends object, - ResponseType extends object, - >( - query: Query<RequestType, ResponseType>, - params: { - auth?: string; - request?: RequestType; - qparam?: any; - response?: ResponseType; - }, - ): void { - const expected = { query, params, auth: params.auth }; - this.expectations.push(expected); - if (this.debug) { - logger.info("saving query as expected", expected); - } - } - - public saveRequestAndGetMockedResponse< - RequestType extends object, - ResponseType extends object, - >( - query: Query<RequestType, ResponseType>, - params: { - auth?: string; - request?: RequestType; - qparam?: any; - response?: ResponseType; - }, - ): MockedResponse { - const queryMade = { query, params, auth: params.auth }; - this.queriesMade.push(queryMade); - const expectedQuery = this.expectations[this.index]; - if (!expectedQuery) { - if (this.debug) { - logger.info("unexpected query made", queryMade); - } - return { queryMade }; - } - - if (this.debug) { - logger.info("tracking query made", { - queryMade, - expectedQuery, - }); - } - this.index++; - return { queryMade, expectedQuery }; - } - - public assertJustExpectedRequestWereMade(): AssertStatus { - let queryNumber = 0; - - while (queryNumber < this.expectations.length) { - const r = this.assertNextRequest(queryNumber); - if (r.result !== "ok") return r; - queryNumber++; - } - return this.assertNoMoreRequestWereMade(queryNumber); - } - - private getLastTestValues(idx: number): TestValues { - const currentExpectedQuery = this.expectations[idx]; - const lastQuery = this.queriesMade[idx]; - - return { currentExpectedQuery, lastQuery }; - } - - private assertNoMoreRequestWereMade(idx: number): AssertStatus { - const { currentExpectedQuery, lastQuery } = this.getLastTestValues(idx); - - if (lastQuery !== undefined) { - return { - result: "error-did-one-more", - made: lastQuery, - }; - } - if (currentExpectedQuery !== undefined) { - return { - result: "error-did-one-less", - expected: currentExpectedQuery, - }; - } - - return { - result: "ok", - }; - } - - private assertNextRequest(index: number): AssertStatus { - const { currentExpectedQuery, lastQuery } = this.getLastTestValues(index); - - if (!currentExpectedQuery) { - return { - result: "error-query-missing", - }; - } - - if (!lastQuery) { - return { - result: "error-did-one-less", - expected: currentExpectedQuery, - }; - } - - if (lastQuery.query.method) { - if (currentExpectedQuery.query.method !== lastQuery.query.method) { - return { - result: "error-difference", - diff: "method", - last: lastQuery.query.method, - expected: currentExpectedQuery.query.method, - index, - }; - } - if (currentExpectedQuery.query.url !== lastQuery.query.url) { - return { - result: "error-difference", - diff: "url", - last: lastQuery.query.url, - expected: currentExpectedQuery.query.url, - index, - }; - } - } - if ( - !deepEquals( - currentExpectedQuery.params?.request, - lastQuery.params?.request, - ) - ) { - return { - result: "error-difference", - diff: "query-body", - expected: currentExpectedQuery.params?.request, - last: lastQuery.params?.request, - index, - }; - } - if ( - !deepEquals(currentExpectedQuery.params?.qparam, lastQuery.params?.qparam) - ) { - return { - result: "error-difference", - diff: "query-params", - expected: currentExpectedQuery.params?.qparam, - last: lastQuery.params?.qparam, - index, - }; - } - if (!deepEquals(currentExpectedQuery.auth, lastQuery.auth)) { - return { - result: "error-difference", - diff: "query-auth", - expected: currentExpectedQuery.auth, - last: lastQuery.auth, - index, - }; - } - - return { - result: "ok", - }; - } -} - -type AssertStatus = - | AssertOk - | AssertQueryNotMadeButExpected - | AssertQueryMadeButNotExpected - | AssertQueryMissing - | AssertExpectedQueryMethodMismatch - | AssertExpectedQueryUrlMismatch - | AssertExpectedQueryAuthMismatch - | AssertExpectedQueryBodyMismatch - | AssertExpectedQueryParamsMismatch; - -interface AssertOk { - result: "ok"; -} - -//trying to assert for a expected query but there is -//no expected query in the queue -interface AssertQueryMissing { - result: "error-query-missing"; -} - -//tested component did one more query that expected -interface AssertQueryNotMadeButExpected { - result: "error-did-one-more"; - made: ExpectationValues; -} - -//tested component didn't make an expected query -interface AssertQueryMadeButNotExpected { - result: "error-did-one-less"; - expected: ExpectationValues; -} - -interface AssertExpectedQueryMethodMismatch { - result: "error-difference"; - diff: "method"; - last: string; - expected: string; - index: number; -} -interface AssertExpectedQueryUrlMismatch { - result: "error-difference"; - diff: "url"; - last: string; - expected: string; - index: number; -} -interface AssertExpectedQueryAuthMismatch { - result: "error-difference"; - diff: "query-auth"; - last: string | undefined; - expected: string | undefined; - index: number; -} -interface AssertExpectedQueryBodyMismatch { - result: "error-difference"; - diff: "query-body"; - last: any; - expected: any; - index: number; -} -interface AssertExpectedQueryParamsMismatch { - result: "error-difference"; - diff: "query-params"; - last: any; - expected: any; - index: number; -} - -/** - * helpers - * - */ -function deepEquals( - a: unknown, - b: unknown, - aStack: Array<unknown> = [], - bStack: Array<unknown> = [], -): boolean { - //one if the element is null or undefined - if (a === null || b === null || b === undefined || a === undefined) { - return a === b; - } - //both are errors - if (a instanceof Error && b instanceof Error) { - return a.message == b.message; - } - //is the same object - if (Object.is(a, b)) { - return true; - } - //both the same class - const name = Object.prototype.toString.call(a); - if (name != Object.prototype.toString.call(b)) { - return false; - } - // - switch (name) { - case "[object Boolean]": - case "[object String]": - case "[object Number]": - if (typeof a !== typeof b) { - // One is a primitive, one a `new Primitive()` - return false; - } else if (typeof a !== "object" && typeof b !== "object") { - // both are proper primitives - return Object.is(a, b); - } else { - // both are `new Primitive()`s - return Object.is(a.valueOf(), b.valueOf()); - } - case "[object Date]": { - const _a = a as Date; - const _b = b as Date; - return _a.getTime() === _b.getTime(); - } - case "[object RegExp]": { - const _a = a as RegExp; - const _b = b as RegExp; - return _a.source === _b.source && _a.flags === _b.flags; - } - case "[object Array]": { - const _a = a as Array<any>; - const _b = b as Array<any>; - if (_a.length !== _b.length) { - return false; - } - } - } - if (typeof a !== "object" || typeof b !== "object") { - return false; - } - - if ( - typeof a === "object" && - typeof b === "object" && - !Array.isArray(a) && - !Array.isArray(b) && - hasIterator(a) && - hasIterator(b) - ) { - return iterable(a, b); - } - - // Used to detect circular references. - let length = aStack.length; - while (length--) { - if (aStack[length] === a) { - return bStack[length] === b; - } else if (bStack[length] === b) { - return false; - } - } - aStack.push(a); - bStack.push(b); - - const aKeys = allKeysFromObject(a); - const bKeys = allKeysFromObject(b); - let keySize = aKeys.length; - - //same number of keys - if (bKeys.length !== keySize) { - return false; - } - - let keyIterator: string; - while (keySize--) { - const _a = a as Record<string, object>; - const _b = b as Record<string, object>; - - keyIterator = aKeys[keySize]; - - const de = deepEquals(_a[keyIterator], _b[keyIterator], aStack, bStack); - if (!de) { - return false; - } - } - - aStack.pop(); - bStack.pop(); - - return true; -} - -function allKeysFromObject(obj: object): Array<string> { - const keys = []; - for (const key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - keys.push(key); - } - } - return keys; -} - -const IteratorSymbol = Symbol.iterator; - -function hasIterator(object: any): boolean { - return !!(object != null && object[IteratorSymbol]); -} - -function iterable( - a: unknown, - b: unknown, - aStack: Array<unknown> = [], - bStack: Array<unknown> = [], -): boolean { - if (a === null || b === null || b === undefined || a === undefined) { - return a === b; - } - if (a.constructor !== b.constructor) { - return false; - } - let length = aStack.length; - while (length--) { - if (aStack[length] === a) { - return bStack[length] === b; - } - } - aStack.push(a); - bStack.push(b); - - const aIterator = (a as any)[IteratorSymbol](); - const bIterator = (b as any)[IteratorSymbol](); - - let nextA = aIterator.next(); - while (!nextA.done) { - const nextB = bIterator.next(); - if (nextB.done || !deepEquals(nextA.value, nextB.value, aStack, bStack)) { - return false; - } - nextA = aIterator.next(); - } - if (!bIterator.next().done) { - return false; - } - - // Remove the first value from the stack of traversed values. - aStack.pop(); - bStack.pop(); - return true; -} diff --git a/packages/web-util/src/tests/swr.ts b/packages/web-util/src/tests/swr.ts @@ -1,112 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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, FunctionalComponent, h, VNode } from "preact"; -import { MockEnvironment } from "./mock.js"; -import { SWRConfig } from "swr"; -import * as swr__internal from "swr/_internal"; -import { TalerError, TalerErrorCode } from "@gnu-taler/taler-util"; - -/** - * Helper for hook that use SWR inside. - * - * buildTestingContext() will return a testing context - * - * @deprecated do not use it, it will be removed - */ -export class SwrMockEnvironment extends MockEnvironment { - constructor(debug = false) { - super(debug); - } - - public buildTestingContext(): FunctionalComponent<{ - children: ComponentChildren; - }> { - const __SAVE_REQUEST_AND_GET_MOCKED_RESPONSE = - this.saveRequestAndGetMockedResponse.bind(this); - - function testingFetcher(params: any): any { - const url = JSON.stringify(params); - const mocked = __SAVE_REQUEST_AND_GET_MOCKED_RESPONSE<any, any>( - { - method: "get", - url, - }, - {}, - ); - - //unexpected query - if (!mocked.expectedQuery) return undefined; - const status = mocked.expectedQuery.query.code ?? 200; - const responsePayload = mocked.expectedQuery.params?.response; - //simulated error - if (status >= 400) { - if ( - responsePayload && - typeof responsePayload === "object" && - "code" in responsePayload && - typeof responsePayload.code === "number" - ) { - throw TalerError.fromUncheckedDetail({ - ...responsePayload, - code: responsePayload.code as TalerErrorCode, - }); - } - throw TalerError.fromUncheckedDetail({ - code: TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, - hint: `Mock request failed with HTTP status ${status}`, - requestUrl: url, - requestMethod: "GET", - httpStatusCode: status, - errorResponse: responsePayload, - }); - } - return responsePayload; - } - - const value: Partial<swr__internal.PublicConfiguration> & { - provider: () => Map<any, any>; - } = { - use: [ - (useSWRNext) => { - return (key, fetcher, config) => { - //prevent the request - //use the testing fetcher instead - return useSWRNext(key, testingFetcher, config); - }; - }, - ], - fetcher: testingFetcher, - //These options are set for ending the test faster - //otherwise SWR will create timeouts that will live after the test finished - loadingTimeout: 0, - dedupingInterval: 0, - shouldRetryOnError: false, - errorRetryInterval: 0, - errorRetryCount: 0, - //clean cache for every test - provider: () => new Map(), - }; - - return function TestingContext({ - children, - }: { - children: ComponentChildren; - }): VNode { - return h(SWRConfig, { value }, children); - }; - } -} diff --git a/packages/web-util/src/utils/route.ts b/packages/web-util/src/utils/route.ts @@ -58,16 +58,6 @@ export type RouteDefinition< url: (p: T) => AppLocation; }; -const nullRountDef = { - pattern: new RegExp(/.*/), - url: () => "" as AppLocation, -}; -export function buildNullRoutDefinition< - T extends ObjectOf<string>, ->(): RouteDefinition<T> { - return nullRountDef; -} - /** * Search path in the pageList * get the values from the path found