taler-typescript-core

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

commit f2abaf6988b6f1da85508770b9d0851f1138b48f
parent b946e91782c06f323efd3cb7491fcd427fc9fbae
Author: Florian Dold <dold@taler.net>
Date:   Mon, 24 Aug 2026 02:28:37 +0200

core bank client: update account and history types for API v12

Diffstat:
Mpackages/taler-util/src/http-client/bank-core.ts | 33++++++++++++++++++++++++++++++++-
Mpackages/taler-util/src/types-taler-corebank.ts | 38+++++++++++++++++++++++++++-----------
Mpackages/web-util/src/context/bank-api.ts | 2+-
3 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/packages/taler-util/src/http-client/bank-core.ts b/packages/taler-util/src/http-client/bank-core.ts @@ -132,7 +132,7 @@ export enum TalerCoreBankCacheEviction { * Uses libtool's current:revision:age versioning. */ export class TalerCoreBankHttpClient { - public static readonly PROTOCOL_VERSION = "12:0:4"; + public static readonly PROTOCOL_VERSION = "12:0:0"; httpLib: HttpRequestLibrary; cacheEvictor: CacheEvictor<TalerCoreBankCacheEviction>; @@ -692,6 +692,37 @@ export class TalerCoreBankHttpClient { } /** + * Read the full transaction history of an account that the bank has marked + * public. This deliberately sends no Authorization header. Private and + * unknown accounts are both reported as not found by Core Bank API v12. + */ + async getPublicTransactions( + username: string, + params?: PaginationParams & LongPollParams, + ) { + const url = new URL( + `accounts/${pathSegment(username)}/transactions`, + this.baseUrl, + ); + addPaginationParams(url, params); + addLongPollingParam(url, params); + const resp = await this.httpLib.fetch(url.href, { method: "GET" }); + switch (resp.status) { + case HttpStatusCode.Ok: + return opSuccessFromHttp( + resp, + codecForBankAccountTransactionsResponse(), + ); + case HttpStatusCode.NoContent: + return opFixedSuccess(resp, { transactions: [] }); + case HttpStatusCode.NotFound: + return opKnownHttpFailure(resp.status, resp); + default: + return opUnknownHttpFailure(resp); + } + } + + /** * https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME-transactions-$TRANSACTION_ID * */ diff --git a/packages/taler-util/src/types-taler-corebank.ts b/packages/taler-util/src/types-taler-corebank.ts @@ -325,6 +325,15 @@ export interface ChallengeContactData { phone?: PhoneNumber; } +/** + * Sparse contact-data update used by account PATCH requests. + * Omitted members are preserved, while null explicitly removes a contact. + */ +export interface ChallengeContactDataPatch { + email?: EmailAddress | null; + phone?: PhoneNumber | null; +} + export interface AccountReconfiguration { // Addresses where to send the TAN for transactions. // Currently only used for cashouts. @@ -332,7 +341,7 @@ export interface AccountReconfiguration { // In the future, might be used for other transactions // as well. // Only admin can change this property. - contact_data?: ChallengeContactData; + contact_data?: ChallengeContactDataPatch; // 'payto' URI of a fiat bank account. // Payments will be sent to this bank account @@ -357,10 +366,10 @@ export interface AccountReconfiguration { // @since **v9** conversion_rate_class_id?: Integer | null; - // If present and not empty, enables 2FA and set the TAN channels used for challenges - // Sending null or an empty array will disable 2FA + // If present and not empty, enables 2FA and sets the TAN channels used for + // challenges. An empty array disables 2FA. // @since **v10** - tan_channels?: TanChannel[] | null; + tan_channels?: TanChannel[]; } export interface AccountPasswordChange { @@ -615,8 +624,8 @@ export interface AccountData { // @deprecated since **v7** // is_locked?: boolean; - // Is 2FA enabled and what channel is used for challenges? - tan_channel?: TanChannel; + // Is 2FA enabled and which channels are used for challenges? + tan_channels?: TanChannel[]; // Current status of the account // active: the account can be used @@ -836,7 +845,12 @@ export const codecForCoreBankConfig = (): Codec<TalerCorebankConfigResponse> => ), ), ) - .property("wire_type", codecOptionalDefault(codecForString(), "iban") as unknown as Codec<string | undefined>) + .property( + "wire_type", + codecOptionalDefault(codecForString(), "iban") as unknown as Codec< + string | undefined + >, + ) .property("wire_transfer_fees", codecOptional(codecForAmountString())) .property("min_wire_transfer_amount", codecOptional(codecForAmountString())) .property("max_wire_transfer_amount", codecOptional(codecForAmountString())) @@ -911,11 +925,13 @@ export const codecForAccountData = (): Codec<AccountData> => .property("is_taler_exchange", codecForBoolean()) .property("conversion_rate_class_id", codecOptional(codecForNumber())) .property( - "tan_channel", + "tan_channels", codecOptional( - codecForEither( - codecForConstString(TanChannel.SMS), - codecForConstString(TanChannel.EMAIL), + codecForList( + codecForEither( + codecForConstString(TanChannel.SMS), + codecForConstString(TanChannel.EMAIL), + ), ), ), ) diff --git a/packages/web-util/src/context/bank-api.ts b/packages/web-util/src/context/bank-api.ts @@ -109,7 +109,7 @@ export const BankApiProvider = ({ const config = await getRemoteConfig(); if (!active) return; checkedFor.current = endpointKey; - if (LibtoolVersion.compare(VERSION, config.version)) { + if (LibtoolVersion.isCompatible(VERSION, config.version)) { setChecked({ type: "ok", config, hints: [] }); } else { setChecked({