commit 592ecda944bf5b32e86f6c42ee8e1f17d9c86451
parent 617ab78264bb3ef200e3568bb6cf9b60ddf5687a
Author: Sebastian <sebasjm@gmail.com>
Date: Sat, 14 Oct 2023 01:19:30 -0300
complet bank api
Diffstat:
7 files changed, 1209 insertions(+), 583 deletions(-)
diff --git a/packages/taler-util/src/http-client/bank-core.ts b/packages/taler-util/src/http-client/bank-core.ts
@@ -0,0 +1,489 @@
+/*
+ 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 {
+ AmountJson,
+ Amounts,
+ Logger
+} from "@gnu-taler/taler-util";
+import {
+ createPlatformHttpLib,
+ expectSuccessResponseOrThrow,
+ HttpRequestLibrary,
+ readSuccessResponseJsonOrThrow
+} from "@gnu-taler/taler-util/http";
+import { AccessToken, codecForAccountData, codecForBankAccountCreateWithdrawalResponse, codecForBankAccountGetWithdrawalResponse, codecForBankAccountTransactionInfo, codecForBankAccountTransactionsResponse, codecForCashoutConversionResponse, codecForCashoutPending, codecForCashouts, codecForCashoutStatusResponse, codecForConversionRatesResponse, codecForCoreBankConfig, codecForGlobalCashouts, codecForListBankAccountsResponse, codecForMonitorResponse, codecForPublicAccountsResponse, codecForTokenSuccessResponse, TalerAuthentication, TalerCorebankApi } from "./types.js";
+import { addPaginationParams, makeBasicAuthHeader, makeBearerTokenAuthHeader, PaginationParams, UserAndPassword, UserAndToken } from "./utils.js";
+import { TalerRevenueHttpClient } from "./bank-revenue.js";
+import { TalerWireGatewayHttpClient } from "./bank-wire.js";
+import { TalerBankIntegrationHttpClient } from "./bank-integration.js";
+
+const logger = new Logger("http-client/core-bank.ts");
+
+export class TalerCoreBankHttpClient {
+ httpLib: HttpRequestLibrary;
+
+ constructor(
+ private baseUrl: string,
+ httpClient?: HttpRequestLibrary,
+ ) {
+ this.httpLib = httpClient ?? createPlatformHttpLib();
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-token
+ *
+ * @returns
+ */
+ async createAccessToken(
+ auth: UserAndPassword,
+ body: TalerAuthentication.TokenRequest,
+ ): Promise<TalerAuthentication.TokenSuccessResponse> {
+ const url = new URL(`accounts/${auth.username}/token`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ headers: {
+ Authorization: makeBasicAuthHeader(auth.username, auth.password),
+ },
+ body
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForTokenSuccessResponse());
+ }
+
+ async deleteAccessToken(
+ auth: UserAndToken,
+ ): Promise<void> {
+ const url = new URL(`accounts/${auth.username}/token`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token),
+ }
+ });
+ return expectSuccessResponseOrThrow(resp);
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME
+ *
+ */
+ async getConfig(): Promise<TalerCorebankApi.Config> {
+ const url = new URL(`config`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET"
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForCoreBankConfig());
+ }
+
+ //
+ // ACCOUNTS
+ //
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post--accounts
+ *
+ */
+ async createAccount(auth: AccessToken, body: TalerCorebankApi.RegisterAccountRequest): Promise<void> {
+ const url = new URL(`accounts`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth)
+ },
+ });
+ return expectSuccessResponseOrThrow(resp);
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#delete--accounts-$USERNAME
+ *
+ */
+ async deleteAccount(auth: UserAndToken): Promise<void> {
+ const url = new URL(`accounts/${auth.username}`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ });
+ return expectSuccessResponseOrThrow(resp);
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#patch--accounts-$USERNAME
+ *
+ */
+ async updateAccount(auth: UserAndToken, body: TalerCorebankApi.AccountReconfiguration): Promise<void> {
+ const url = new URL(`accounts/${auth.username}`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "PATCH",
+ body,
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ });
+ return expectSuccessResponseOrThrow(resp);
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#patch--accounts-$USERNAME-auth
+ *
+ */
+ async updatePassword(auth: UserAndToken, body: TalerCorebankApi.AccountPasswordChange): Promise<void> {
+ const url = new URL(`accounts/${auth.username}`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "PATCH",
+ body,
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ });
+ return expectSuccessResponseOrThrow(resp);
+ }
+
+ /**
+ * https://docs.taler.net/core/get-$BANK_API_BASE_URL-public-accounts
+ *
+ */
+ async getPublicAccounts(): Promise<TalerCorebankApi.PublicAccountsResponse> {
+ const url = new URL(`public-accounts`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ },
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForPublicAccountsResponse());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#get--accounts
+ *
+ */
+ async getAccounts(auth: AccessToken): Promise<TalerCorebankApi.ListBankAccountsResponse> {
+ const url = new URL(`accounts`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth)
+ },
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForListBankAccountsResponse());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME
+ *
+ */
+ async getAccount(auth: UserAndToken): Promise<TalerCorebankApi.AccountData> {
+ const url = new URL(`accounts/${auth.username}`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForAccountData());
+ }
+
+ //
+ // TRANSACTIONS
+ //
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#get-$BANK_API_BASE_URL-accounts-$account_name-transactions
+ *
+ */
+ async getTransactions(auth: UserAndToken, pagination?: PaginationParams): Promise<TalerCorebankApi.BankAccountTransactionsResponse> {
+ const url = new URL(`accounts/${auth.username}/transactions`, this.baseUrl);
+ addPaginationParams(url, pagination)
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForBankAccountTransactionsResponse());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#get-$BANK_API_BASE_URL-accounts-$account_name-transactions-$transaction_id
+ *
+ */
+ async getTransactionById(auth: UserAndToken, txid: number): Promise<TalerCorebankApi.BankAccountTransactionInfo> {
+ const url = new URL(`accounts/${auth.username}/transactions/${String(txid)}`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForBankAccountTransactionInfo());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post-$BANK_API_BASE_URL-accounts-$account_name-transactions
+ *
+ */
+ async createTransaction(auth: UserAndToken, body: TalerCorebankApi.CreateBankAccountTransactionCreate): Promise<void> {
+ const url = new URL(`accounts/${auth.username}/transactions`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ body,
+ });
+ return expectSuccessResponseOrThrow(resp);
+ }
+
+ //
+ // WITHDRAWALS
+ //
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post-$BANK_API_BASE_URL-accounts-$account_name-withdrawals
+ *
+ */
+ async createWithdrawal(auth: UserAndToken, body: TalerCorebankApi.BankAccountCreateWithdrawalRequest): Promise<TalerCorebankApi.BankAccountCreateWithdrawalResponse> {
+ const url = new URL(`accounts/${auth.username}/withdrawals`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ body,
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForBankAccountCreateWithdrawalResponse());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post-$BANK_API_BASE_URL-accounts-$account_name-withdrawals
+ *
+ */
+ async getWithdrawalById(wid: string): Promise<TalerCorebankApi.BankAccountGetWithdrawalResponse> {
+ const url = new URL(`withdrawals/${wid}`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForBankAccountGetWithdrawalResponse());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post-$BANK_API_BASE_URL-withdrawals-$withdrawal_id-abort
+ *
+ */
+ async abortWithdrawalById(wid: string): Promise<void> {
+ const url = new URL(`withdrawals/${wid}/abort`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ });
+ return expectSuccessResponseOrThrow(resp);
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post-$BANK_API_BASE_URL-withdrawals-$withdrawal_id-confirm
+ *
+ */
+ async confirmWithdrawalById(wid: string): Promise<void> {
+ const url = new URL(`withdrawals/${wid}/confirm`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ });
+ return expectSuccessResponseOrThrow(resp);
+ }
+
+ //
+ // CASHOUTS
+ //
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts
+ *
+ */
+ async createCashout(auth: UserAndToken, body: TalerCorebankApi.CashoutRequest): Promise<TalerCorebankApi.CashoutPending> {
+ const url = new URL(`accounts/${auth.username}/cashouts`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ body,
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForCashoutPending());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts-$CASHOUT_ID-abort
+ *
+ */
+ async abortCashoutById(auth: UserAndToken, cid: string): Promise<void> {
+ const url = new URL(`accounts/${auth.username}/cashouts/${cid}/abort`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ });
+ return expectSuccessResponseOrThrow(resp);
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts-$CASHOUT_ID-confirm
+ *
+ */
+ async confirmCashoutById(auth: UserAndToken, cid: string, body: TalerCorebankApi.CashoutConfirmRequest): Promise<void> {
+ const url = new URL(`accounts/${auth.username}/cashouts/${cid}/confirm`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ body,
+ });
+ return expectSuccessResponseOrThrow(resp);
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts-$CASHOUT_ID-confirm
+ *
+ */
+ async getCashoutRate(conversion: { debit?: AmountJson, credit?: AmountJson }): Promise<TalerCorebankApi.CashoutConversionResponse> {
+ const url = new URL(`cashout-rate`, this.baseUrl);
+ if (conversion.debit) {
+ url.searchParams.set("amount_debit", Amounts.stringify(conversion.debit))
+ }
+ if (conversion.credit) {
+ url.searchParams.set("amount_debit", Amounts.stringify(conversion.credit))
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForCashoutConversionResponse());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME-cashouts
+ *
+ */
+ async getAccountCashouts(auth: UserAndToken): Promise<TalerCorebankApi.Cashouts> {
+ const url = new URL(`accounts/${auth.username}/cashouts`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForCashouts());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#get--cashouts
+ *
+ */
+ async getGlobalCashouts(auth: AccessToken): Promise<TalerCorebankApi.GlobalCashouts> {
+ const url = new URL(`cashouts`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth)
+ },
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForGlobalCashouts());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME-cashouts-$CASHOUT_ID
+ *
+ */
+ async getCashoutById(auth: UserAndToken, cid: string): Promise<TalerCorebankApi.CashoutStatusResponse> {
+ const url = new URL(`accounts/${auth.username}/cashouts/${cid}`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth.token)
+ },
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForCashoutStatusResponse());
+ }
+
+ //
+ // CONVERSION RATE
+ //
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#get--conversion-rates
+ *
+ */
+ async getConversionRates(): Promise<TalerCorebankApi.ConversionRatesResponse> {
+ const url = new URL(`conversion-rates`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForConversionRatesResponse());
+ }
+
+ //
+ // MONITOR
+ //
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#get--monitor
+ *
+ */
+ async getMonitor(params: { timeframe: TalerCorebankApi.MonitorTimeframeParam, which: number }): Promise<TalerCorebankApi.MonitorResponse> {
+ const url = new URL(`monitor`, this.baseUrl);
+ url.searchParams.set("timeframe", params.timeframe.toString())
+ url.searchParams.set("which", String(params.which))
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForMonitorResponse());
+ }
+
+ //
+ // Others API
+ //
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#taler-bank-integration-api
+ *
+ */
+ getIntegrationAPI(): TalerBankIntegrationHttpClient {
+ const url = new URL(`taler-integration`, this.baseUrl);
+ return new TalerBankIntegrationHttpClient(url.href, this.httpLib)
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#taler-bank-integration-api
+ *
+ */
+ getWireGatewayAPI(username: string): TalerWireGatewayHttpClient {
+ const url = new URL(`accounts/${username}/taler-wire-gateway`, this.baseUrl);
+ return new TalerWireGatewayHttpClient(url.href, username, this.httpLib)
+ }
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#taler-bank-integration-api
+ *
+ */
+ getRevenueAPI(username: string): TalerRevenueHttpClient {
+ const url = new URL(`accounts/${username}/taler-revenue`, this.baseUrl);
+ return new TalerRevenueHttpClient(url.href, username, this.httpLib,)
+ }
+
+}
+
diff --git a/packages/taler-util/src/http-client/bank-integration.ts b/packages/taler-util/src/http-client/bank-integration.ts
@@ -0,0 +1,44 @@
+import { HttpRequestLibrary, readSuccessResponseJsonOrThrow } from "../http-common.js";
+import { createPlatformHttpLib } from "../http.js";
+import { codecForBankWithdrawalOperationPostResponse } from "../taler-types.js";
+import { TalerBankIntegrationApi, codecForBankVersion, codecForBankWithdrawalOperationStatus } from "./types.js";
+
+export class TalerBankIntegrationHttpClient {
+ httpLib: HttpRequestLibrary;
+
+ constructor(
+ private baseUrl: string,
+ httpClient?: HttpRequestLibrary,
+ ) {
+ this.httpLib = httpClient ?? createPlatformHttpLib();
+ }
+
+ /**
+ * https://docs.taler.net/core/api-bank-integration.html#get-$BANK_API_BASE_URL-withdrawal-operation-$wopid
+ *
+ */
+ async getWithdrawalOperationById(woid: string, timeoutMs?: number): Promise<TalerBankIntegrationApi.BankWithdrawalOperationStatus> {
+ const url = new URL(`withdrawal-operation/${woid}`, this.baseUrl);
+ if (timeoutMs) {
+ url.searchParams.set("long_poll_ms", String(timeoutMs))
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET"
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForBankWithdrawalOperationStatus());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-bank-integration.html#post-$BANK_API_BASE_URL-withdrawal-operation-$wopid
+ *
+ */
+ async completeWithdrawalOperationById(woid: string): Promise<TalerBankIntegrationApi.BankWithdrawalOperationPostResponse> {
+ const url = new URL(`withdrawal-operation/${woid}`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForBankWithdrawalOperationPostResponse());
+ }
+
+}
+
diff --git a/packages/taler-util/src/http-client/bank-revenue.ts b/packages/taler-util/src/http-client/bank-revenue.ts
@@ -0,0 +1,32 @@
+import { HttpRequestLibrary, makeBasicAuthHeader, readSuccessResponseJsonOrThrow } from "../http-common.js";
+import { createPlatformHttpLib } from "../http.js";
+import { TalerRevenueApi, codecForMerchantIncomingHistory } from "./types.js";
+import { UserAndPassword } from "./utils.js";
+
+export class TalerRevenueHttpClient {
+ httpLib: HttpRequestLibrary;
+
+ constructor(
+ private baseUrl: string,
+ private username: string,
+ httpClient?: HttpRequestLibrary,
+ ) {
+ this.httpLib = httpClient ?? createPlatformHttpLib();
+ }
+
+ /**
+ * https://docs.taler.net/core/api-bank-revenue.html#get-$BASE_URL-history
+ *
+ * @returns
+ */
+ async getHistory(auth: string): Promise<TalerRevenueApi.MerchantIncomingHistory> {
+ const url = new URL(`history`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: makeBasicAuthHeader(this.username, auth),
+ }
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForMerchantIncomingHistory());
+ }
+}
+\ No newline at end of file
diff --git a/packages/taler-util/src/http-client/bank-wire.ts b/packages/taler-util/src/http-client/bank-wire.ts
@@ -0,0 +1,98 @@
+import { HttpRequestLibrary, makeBasicAuthHeader, readSuccessResponseJsonOrThrow } from "../http-common.js";
+import { createPlatformHttpLib } from "../http.js";
+import { TalerWireGatewayApi, codecForAddIncomingResponse, codecForIncomingHistory, codecForOutgoingHistory, codecForTransferResponse } from "./types.js";
+import { PaginationParams, UserAndPassword, addPaginationParams } from "./utils.js";
+
+/**
+ * The API is used by the exchange to trigger transactions and query
+ * incoming transactions, as well as by the auditor to query incoming
+ * and outgoing transactions.
+ *
+ * https://docs.taler.net/core/api-bank-wire.html
+ */
+export class TalerWireGatewayHttpClient {
+ httpLib: HttpRequestLibrary;
+
+ constructor(
+ private baseUrl: string,
+ private username: string,
+ httpClient?: HttpRequestLibrary,
+ ) {
+ this.httpLib = httpClient ?? createPlatformHttpLib();
+ }
+
+ /**
+ * https://docs.taler.net/core/api-bank-wire.html#post-$BASE_URL-transfer
+ *
+ */
+ async transfer(
+ auth: string,
+ body: TalerWireGatewayApi.TransferRequest,
+ ): Promise<TalerWireGatewayApi.TransferResponse> {
+ const url = new URL(`transfer`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ headers: {
+ Authorization: makeBasicAuthHeader(this.username, auth),
+ },
+ body
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForTransferResponse());
+ }
+
+ /**
+ * https://docs.taler.net/core/api-bank-wire.html#get-$BASE_URL-history-incoming
+ *
+ */
+ async getHistoryIncoming(
+ auth: string,
+ pagination?: PaginationParams
+ ): Promise<TalerWireGatewayApi.IncomingHistory> {
+ const url = new URL(`history/incoming`, this.baseUrl);
+ addPaginationParams(url, pagination)
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: makeBasicAuthHeader(this.username, auth),
+ }
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForIncomingHistory());
+ }
+ /**
+ * https://docs.taler.net/core/api-bank-wire.html#get-$BASE_URL-history-outgoing
+ *
+ */
+ async getHistoryOutgoing(
+ auth: string,
+ pagination?: PaginationParams
+ ): Promise<TalerWireGatewayApi.OutgoingHistory> {
+ const url = new URL(`history/outgoing`, this.baseUrl);
+ addPaginationParams(url, pagination)
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: makeBasicAuthHeader(this.username, auth),
+ }
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForOutgoingHistory());
+ }
+ /**
+ * https://docs.taler.net/core/api-bank-wire.html#post-$BASE_URL-admin-add-incoming
+ *
+ */
+ async addIncoming(
+ auth: string,
+ body: TalerWireGatewayApi.AddIncomingRequest,
+ ): Promise<TalerWireGatewayApi.AddIncomingResponse> {
+ const url = new URL(`admin/add-incoming`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ headers: {
+ Authorization: makeBasicAuthHeader(this.username, auth),
+ },
+ body
+ });
+ return readSuccessResponseJsonOrThrow(resp, codecForAddIncomingResponse());
+ }
+}
+
diff --git a/packages/taler-util/src/http-client/core-bank.ts b/packages/taler-util/src/http-client/core-bank.ts
@@ -1,523 +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 {
- AmountJson,
- Amounts,
- Logger
-} from "@gnu-taler/taler-util";
-import {
- createPlatformHttpLib,
- expectSuccessResponseOrThrow,
- HttpRequestLibrary,
- readSuccessResponseJsonOrThrow
-} from "@gnu-taler/taler-util/http";
-import { AccessToken, codecForAccountData, codecForBankAccountCreateWithdrawalResponse, codecForBankAccountGetWithdrawalResponse, codecForBankAccountTransactionInfo, codecForBankAccountTransactionsResponse, codecForCashoutConversionResponse, codecForCashoutPending, codecForCashouts, codecForCashoutStatusResponse, codecForConversionRatesResponse, codecForCoreBankConfig, codecForGlobalCashouts, codecForListBankAccountsResponse, codecForMonitorResponse, codecForPublicAccountsResponse, codecForTokenSuccessResponse, TalerAuthentication, TalerCorebankApi } from "./types.js";
-import { addPaginationParams, makeBasicAuthHeader, makeBearerTokenAuthHeader, PaginationParams, UserAndPassword, UserAndToken } from "./utils.js";
-
-const logger = new Logger("http-client/core-bank.ts");
-
-export class TalerCoreBankHttpClient {
- httpLib: HttpRequestLibrary;
-
- constructor(
- private baseUrl: string,
- httpClient?: HttpRequestLibrary,
- ) {
- this.httpLib = httpClient ?? createPlatformHttpLib();
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-token
- *
- * @returns
- */
- async createAccessToken(
- auth: UserAndPassword,
- body: TalerAuthentication.TokenRequest,
- ): Promise<TalerAuthentication.TokenSuccessResponse> {
- const url = new URL(`accounts/${auth.username}/token`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "POST",
- headers: {
- Authorization: makeBasicAuthHeader(auth.username, auth.password),
- },
- body
- });
- return readSuccessResponseJsonOrThrow(resp, codecForTokenSuccessResponse());
- }
-
- async deleteAccessToken(
- auth: UserAndToken,
- ): Promise<void> {
- const url = new URL(`accounts/${auth.username}/token`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "DELETE",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token),
- }
- });
- return expectSuccessResponseOrThrow(resp);
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME
- *
- */
- async getConfig(): Promise<TalerCorebankApi.Config> {
- const url = new URL(`config`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET"
- });
- return readSuccessResponseJsonOrThrow(resp, codecForCoreBankConfig());
- }
-
- //
- // ACCOUNTS
- //
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post--accounts
- *
- */
- async createAccount(auth: AccessToken, body: TalerCorebankApi.RegisterAccountRequest): Promise<void> {
- const url = new URL(`accounts`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "POST",
- body,
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth)
- },
- });
- return expectSuccessResponseOrThrow(resp);
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#delete--accounts-$USERNAME
- *
- */
- async deleteAccount(auth: UserAndToken): Promise<void> {
- const url = new URL(`accounts/${auth.username}`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "DELETE",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- });
- return expectSuccessResponseOrThrow(resp);
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#patch--accounts-$USERNAME
- *
- */
- async updateAccount(auth: UserAndToken, body: TalerCorebankApi.AccountReconfiguration): Promise<void> {
- const url = new URL(`accounts/${auth.username}`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "PATCH",
- body,
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- });
- return expectSuccessResponseOrThrow(resp);
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#patch--accounts-$USERNAME-auth
- *
- */
- async updatePassword(auth: UserAndToken, body: TalerCorebankApi.AccountPasswordChange): Promise<void> {
- const url = new URL(`accounts/${auth.username}`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "PATCH",
- body,
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- });
- return expectSuccessResponseOrThrow(resp);
- }
-
- /**
- * https://docs.taler.net/core/get-$BANK_API_BASE_URL-public-accounts
- *
- */
- async getPublicAccounts(): Promise<TalerCorebankApi.PublicAccountsResponse> {
- const url = new URL(`public-accounts`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- headers: {
- },
- });
- return readSuccessResponseJsonOrThrow(resp, codecForPublicAccountsResponse());
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#get--accounts
- *
- */
- async getAccounts(auth: AccessToken): Promise<TalerCorebankApi.ListBankAccountsResponse> {
- const url = new URL(`accounts`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth)
- },
- });
- return readSuccessResponseJsonOrThrow(resp, codecForListBankAccountsResponse());
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME
- *
- */
- async getAccount(auth: UserAndToken): Promise<TalerCorebankApi.AccountData> {
- const url = new URL(`accounts/${auth.username}`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- });
- return readSuccessResponseJsonOrThrow(resp, codecForAccountData());
- }
-
- //
- // TRANSACTIONS
- //
-
- /**
- * https://docs.taler.net/core/api-corebank.html#get-$BANK_API_BASE_URL-accounts-$account_name-transactions
- *
- */
- async getTransactions(auth: UserAndToken, pagination?: PaginationParams): Promise<TalerCorebankApi.BankAccountTransactionsResponse> {
- const url = new URL(`accounts/${auth.username}/transactions`, this.baseUrl);
- addPaginationParams(url, pagination)
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- });
- return readSuccessResponseJsonOrThrow(resp, codecForBankAccountTransactionsResponse());
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#get-$BANK_API_BASE_URL-accounts-$account_name-transactions-$transaction_id
- *
- */
- async getTransactionById(auth: UserAndToken, txid: number): Promise<TalerCorebankApi.BankAccountTransactionInfo> {
- const url = new URL(`accounts/${auth.username}/transactions/${String(txid)}`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- });
- return readSuccessResponseJsonOrThrow(resp, codecForBankAccountTransactionInfo());
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post-$BANK_API_BASE_URL-accounts-$account_name-transactions
- *
- */
- async createTransaction(auth: UserAndToken, body: TalerCorebankApi.CreateBankAccountTransactionCreate): Promise<void> {
- const url = new URL(`accounts/${auth.username}/transactions`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "POST",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- body,
- });
- return expectSuccessResponseOrThrow(resp);
- }
-
- //
- // WITHDRAWALS
- //
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post-$BANK_API_BASE_URL-accounts-$account_name-withdrawals
- *
- */
- async createWithdrawal(auth: UserAndToken, body: TalerCorebankApi.BankAccountCreateWithdrawalRequest): Promise<TalerCorebankApi.BankAccountCreateWithdrawalResponse> {
- const url = new URL(`accounts/${auth.username}/withdrawals`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "POST",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- body,
- });
- return readSuccessResponseJsonOrThrow(resp, codecForBankAccountCreateWithdrawalResponse());
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post-$BANK_API_BASE_URL-accounts-$account_name-withdrawals
- *
- */
- async getWithdrawalById(wid: string): Promise<TalerCorebankApi.BankAccountGetWithdrawalResponse> {
- const url = new URL(`withdrawals/${wid}`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- });
- return readSuccessResponseJsonOrThrow(resp, codecForBankAccountGetWithdrawalResponse());
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post-$BANK_API_BASE_URL-withdrawals-$withdrawal_id-abort
- *
- */
- async abortWithdrawalById(wid: string): Promise<void> {
- const url = new URL(`withdrawals/${wid}/abort`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "POST",
- });
- return expectSuccessResponseOrThrow(resp);
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post-$BANK_API_BASE_URL-withdrawals-$withdrawal_id-confirm
- *
- */
- async confirmWithdrawalById(wid: string): Promise<void> {
- const url = new URL(`withdrawals/${wid}/confirm`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "POST",
- });
- return expectSuccessResponseOrThrow(resp);
- }
-
- //
- // CASHOUTS
- //
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts
- *
- */
- async createCashout(auth: UserAndToken, body: TalerCorebankApi.CashoutRequest): Promise<TalerCorebankApi.CashoutPending> {
- const url = new URL(`accounts/${auth.username}/cashouts`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "POST",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- body,
- });
- return readSuccessResponseJsonOrThrow(resp, codecForCashoutPending());
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts-$CASHOUT_ID-abort
- *
- */
- async abortCashoutById(auth: UserAndToken, cid: string): Promise<void> {
- const url = new URL(`accounts/${auth.username}/cashouts/${cid}/abort`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "POST",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- });
- return expectSuccessResponseOrThrow(resp);
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts-$CASHOUT_ID-confirm
- *
- */
- async confirmCashoutById(auth: UserAndToken, cid: string, body: TalerCorebankApi.CashoutConfirmRequest): Promise<void> {
- const url = new URL(`accounts/${auth.username}/cashouts/${cid}/confirm`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "POST",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- body,
- });
- return expectSuccessResponseOrThrow(resp);
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts-$CASHOUT_ID-confirm
- *
- */
- async getCashoutRate(conversion: { debit?: AmountJson, credit?: AmountJson }): Promise<TalerCorebankApi.CashoutConversionResponse> {
- const url = new URL(`cashout-rate`, this.baseUrl);
- if (conversion.debit) {
- url.searchParams.set("amount_debit", Amounts.stringify(conversion.debit))
- }
- if (conversion.credit) {
- url.searchParams.set("amount_debit", Amounts.stringify(conversion.credit))
- }
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- });
- return readSuccessResponseJsonOrThrow(resp, codecForCashoutConversionResponse());
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME-cashouts
- *
- */
- async getAccountCashouts(auth: UserAndToken): Promise<TalerCorebankApi.Cashouts> {
- const url = new URL(`accounts/${auth.username}/cashouts`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- });
- return readSuccessResponseJsonOrThrow(resp, codecForCashouts());
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#get--cashouts
- *
- */
- async getGlobalCashouts(auth: AccessToken): Promise<TalerCorebankApi.GlobalCashouts> {
- const url = new URL(`cashouts`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth)
- },
- });
- return readSuccessResponseJsonOrThrow(resp, codecForGlobalCashouts());
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME-cashouts-$CASHOUT_ID
- *
- */
- async getCashoutById(auth: UserAndToken, cid: string): Promise<TalerCorebankApi.CashoutStatusResponse> {
- const url = new URL(`accounts/${auth.username}/cashouts/${cid}`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- });
- return readSuccessResponseJsonOrThrow(resp, codecForCashoutStatusResponse());
- }
-
- //
- // CONVERSION RATE
- //
-
- /**
- * https://docs.taler.net/core/api-corebank.html#get--conversion-rates
- *
- */
- async getConversionRates(): Promise<TalerCorebankApi.ConversionRatesResponse> {
- const url = new URL(`conversion-rates`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- });
- return readSuccessResponseJsonOrThrow(resp, codecForConversionRatesResponse());
- }
-
- //
- // MONITOR
- //
-
- /**
- * https://docs.taler.net/core/api-corebank.html#get--monitor
- *
- */
- async getMonitor(params: { timeframe: TalerCorebankApi.MonitorTimeframeParam, which: number }): Promise<TalerCorebankApi.MonitorResponse> {
- const url = new URL(`monitor`, this.baseUrl);
- url.searchParams.set("timeframe", params.timeframe.toString())
- url.searchParams.set("which", String(params.which))
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- });
- return readSuccessResponseJsonOrThrow(resp, codecForMonitorResponse());
- }
-
- //
- // Others API
- //
-
- /**
- * https://docs.taler.net/core/api-corebank.html#taler-bank-integration-api
- *
- */
- getIntegrationAPI(): TalerBankIntegrationHttpClient {
- const url = new URL(`taler-integration`, this.baseUrl);
- return new TalerBankIntegrationHttpClient(url.href, this.httpLib)
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#taler-bank-integration-api
- *
- */
- getWireGatewayAPI(username: string): TalerWireGatewayHttpClient {
- const url = new URL(`accounts/${username}/taler-wire-gateway`, this.baseUrl);
- return new TalerWireGatewayHttpClient(url.href, username, this.httpLib)
- }
-
- /**
-* https://docs.taler.net/core/api-corebank.html#taler-bank-integration-api
-*
-*/
- getRevenueAPI(username: string): TalerRevenueHttpClient {
- const url = new URL(`accounts/${username}/taler-revenue`, this.baseUrl);
- return new TalerRevenueHttpClient(url.href, username, this.httpLib,)
- }
-
-}
-
-export class TalerBankIntegrationHttpClient {
- httpLib: HttpRequestLibrary;
-
- constructor(
- private baseUrl: string,
- httpClient?: HttpRequestLibrary,
- ) {
- this.httpLib = httpClient ?? createPlatformHttpLib();
- }
-
-}
-
-export class TalerWireGatewayHttpClient {
- httpLib: HttpRequestLibrary;
-
- constructor(
- private baseUrl: string,
- private username: string,
- httpClient?: HttpRequestLibrary,
- ) {
- this.httpLib = httpClient ?? createPlatformHttpLib();
- }
-
-}
-
-export class TalerRevenueHttpClient {
- httpLib: HttpRequestLibrary;
-
- constructor(
- private baseUrl: string,
- private username: string,
- httpClient?: HttpRequestLibrary,
- ) {
- this.httpLib = httpClient ?? createPlatformHttpLib();
- }
-
-}
-\ No newline at end of file
diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts
@@ -1,42 +1,120 @@
-import { codecForAmountJson, codecForAmountString } from "../amounts.js";
-import { TalerCorebankApiClient } from "../bank-api-client.js";
-import { Codec, buildCodecForObject, codecForAny, codecForBoolean, codecForConstString, codecForEither, codecForList, codecForMap, codecForNumber, codecForString, codecOptional } from "../codec.js";
+import { codecForAmountString } from "../amounts.js";
+import { Codec, buildCodecForObject, buildCodecForUnion, codecForBoolean, codecForConstString, codecForEither, codecForList, codecForMap, codecForNumber, codecForString, codecOptional } from "../codec.js";
import { codecForTimestamp } from "../time.js";
+///
+/// HASH
+///
+
+// 64-byte hash code.
type HashCode = string;
+
+// 32-byte hash code.
+type ShortHashCode = string;
+
+// 16-byte salt.
+type WireSalt = string;
+
+type SHA256HashCode = ShortHashCode;
+
+type SHA512HashCode = HashCode;
+
+// 32-byte nonce value, must only be used once.
+type CSNonce = string;
+
+// 32-byte nonce value, must only be used once.
+type RefreshMasterSeed = string;
+
+// 32-byte value representing a point on Curve25519.
+type Cs25519Point = string;
+
+// 32-byte value representing a scalar multiplier
+// for scalar operations on points on Curve25519.
+type Cs25519Scalar = string;
+
+///
+/// KEYS
+///
+
+// 16-byte access token used to authorize access.
+type ClaimToken = string;
+
+// EdDSA and ECDHE public keys always point on Curve25519
+// and represented using the standard 256 bits Ed25519 compact format,
+// converted to Crockford Base32.
type EddsaPublicKey = string;
-type EddsaSignature = string;
+
+// EdDSA and ECDHE public keys always point on Curve25519
+// and represented using the standard 256 bits Ed25519 compact format,
+// converted to Crockford Base32.
+type EddsaPrivateKey = string;
+
+// Edx25519 public keys are points on Curve25519 and represented using the
+// standard 256 bits Ed25519 compact format converted to Crockford
+// Base32.
+type Edx25519PublicKey = string;
+
+// Edx25519 private keys are always points on Curve25519
+// and represented using the standard 256 bits Ed25519 compact format,
+// converted to Crockford Base32.
+type Edx25519PrivateKey = string;
+
+// EdDSA and ECDHE public keys always point on Curve25519
+// and represented using the standard 256 bits Ed25519 compact format,
+// converted to Crockford Base32.
+type EcdhePublicKey = string;
+
+// Point on Curve25519 represented using the standard 256 bits Ed25519 compact format,
+// converted to Crockford Base32.
+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.
+type EcdhePrivateKey = string;
+
+type CoinPublicKey = EddsaPublicKey;
+
+// RSA public key converted to Crockford Base32.
+type RsaPublicKey = string;
+
+type Integer = number;
+
type WireTransferIdentifierRawP = string;
-type RelativeTime = {
- d_us: number | "forever"
-};
+// Subset of numbers: Integers in the
+// inclusive range 0 .. (2^53 - 1).
+type SafeUint64 = number;
+
+// The string must be a data URL according to RFC 2397
+// with explicit mediatype and base64 parameters.
+//
+// data:<mediatype>;base64,<data>
+//
+// Supported mediatypes are image/jpeg and image/png.
+// Invalid strings will be rejected by the wallet.
type ImageDataUrl = string;
-interface WithId {
- id: string;
-}
+
+// <Currency>:<DecimalAmount>.
+type Amount = string;
+
+type WadId = string;
interface Timestamp {
- // Milliseconds since epoch, or the special
- // value "forever" to represent an event that will
+ // Seconds since epoch, or the special
+ // value "never" to represent an event that will
// never happen.
t_s: number | "never";
}
-interface Duration {
- d_us: number | "forever";
-}
-interface WithId {
- id: string;
+interface RelativeTime {
+ // Duration in microseconds or "forever"
+ // to represent an infinite duration. Numeric
+ // values are capped at 2^53 - 1 inclusive.
+ d_us: number | "forever";
}
-type UUID = string;
-type Integer = number;
-
-type Amount = string;
-
-
export interface LoginToken {
token: AccessToken,
expiration: Timestamp,
@@ -78,7 +156,7 @@ export namespace TalerAuthentication {
}
}
-interface CurrencySpecification {
+export interface CurrencySpecification {
// Name of the currency.
name: string;
@@ -262,53 +340,173 @@ export const codecForGlobalCashouts =
export const codecForGlobalCashoutInfo =
(): Codec<TalerCorebankApi.GlobalCashoutInfo> =>
buildCodecForObject<TalerCorebankApi.GlobalCashoutInfo>()
- .property("cashout_id", codecForString())
- .property("username", codecForString())
- .property("status", codecForEither(codecForConstString("pending"), codecForConstString("confirmed"),))
+ .property("cashout_id", codecForString())
+ .property("username", codecForString())
+ .property("status", codecForEither(codecForConstString("pending"), codecForConstString("confirmed"),))
.build("TalerCorebankApi.GlobalCashoutInfo");
export const codecForCashoutStatusResponse =
(): Codec<TalerCorebankApi.CashoutStatusResponse> =>
buildCodecForObject<TalerCorebankApi.CashoutStatusResponse>()
- .property("amount_credit", codecForAmountString())
- .property("amount_debit", codecForAmountString())
- .property("confirmation_time", codecForTimestamp)
- .property("creation_time", codecForTimestamp)
- .property("credit_payto_uri", codecForPaytoURI())
- .property("status", codecForEither(codecForConstString("pending"), codecForConstString("confirmed")))
- .property("subject", codecForString())
- .build("TalerCorebankApi.CashoutStatusResponse");
+ .property("amount_credit", codecForAmountString())
+ .property("amount_debit", codecForAmountString())
+ .property("confirmation_time", codecForTimestamp)
+ .property("creation_time", codecForTimestamp)
+ .property("credit_payto_uri", codecForPaytoURI())
+ .property("status", codecForEither(codecForConstString("pending"), codecForConstString("confirmed")))
+ .property("subject", codecForString())
+ .build("TalerCorebankApi.CashoutStatusResponse");
export const codecForConversionRatesResponse =
(): Codec<TalerCorebankApi.ConversionRatesResponse> =>
buildCodecForObject<TalerCorebankApi.ConversionRatesResponse>()
- .property("buy_at_ratio", codecForDecimalNumber())
- .property("buy_in_fee", codecForDecimalNumber())
- .property("sell_at_ratio", codecForDecimalNumber())
- .property("sell_out_fee", codecForDecimalNumber())
- .build("TalerCorebankApi.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<TalerCorebankApi.MonitorResponse> =>
buildCodecForObject<TalerCorebankApi.MonitorResponse>()
- .property("cashinCount", codecForNumber())
- .property("cashinExternalVolume", codecForAmountString())
- .property("cashoutCount", codecForNumber())
- .property("cashoutExternalVolume", codecForAmountString())
- .property("talerPayoutCount", codecForNumber())
- .property("talerPayoutInternalVolume", codecForAmountString())
- .build("TalerCorebankApi.MonitorResponse");
+ .property("cashinCount", codecForNumber())
+ .property("cashinExternalVolume", codecForAmountString())
+ .property("cashoutCount", codecForNumber())
+ .property("cashoutExternalVolume", codecForAmountString())
+ .property("talerPayoutCount", codecForNumber())
+ .property("talerPayoutInternalVolume", codecForAmountString())
+ .build("TalerCorebankApi.MonitorResponse");
+
+export const codecForBankVersion =
+ (): Codec<TalerBankIntegrationApi.BankVersion> =>
+ buildCodecForObject<TalerBankIntegrationApi.BankVersion>()
+ .property("currency", codecForCurrencyName())
+ .property("currency_specification", codecForCurrencySpecificiation())
+ .property("name", codecForConstString("taler-bank-integration"))
+ .property("version", codecForLibtoolVersion())
+ .build("TalerBankIntegrationApi.BankVersion");
+
+export const codecForBankWithdrawalOperationStatus =
+ (): Codec<TalerBankIntegrationApi.BankWithdrawalOperationStatus> =>
+ buildCodecForObject<TalerBankIntegrationApi.BankWithdrawalOperationStatus>()
+ .property("aborted", codecForBoolean())
+ .property("amount", codecForAmountString())
+ .property("confirm_transfer_url", codecOptional(codecForURL()))
+ .property("selection_done", codecForBoolean())
+ .property("sender_wire", codecForPaytoURI())
+ .property("suggested_exchange", codecOptional(codecForString()))
+ .property("transfer_done", codecForBoolean())
+ .property("wire_types", codecForList(codecForString()))
+ .build("TalerBankIntegrationApi.BankWithdrawalOperationStatus");
+
+export const codecForBankWithdrawalOperationPostResponse =
+ (): Codec<TalerBankIntegrationApi.BankWithdrawalOperationPostResponse> =>
+ buildCodecForObject<TalerBankIntegrationApi.BankWithdrawalOperationPostResponse>()
+ .property("confirm_transfer_url", codecForURL())
+ .property("transfer_done", codecForBoolean())
+ .build("TalerBankIntegrationApi.BankWithdrawalOperationPostResponse");
+
+export const codecForMerchantIncomingHistory =
+ (): Codec<TalerRevenueApi.MerchantIncomingHistory> =>
+ buildCodecForObject<TalerRevenueApi.MerchantIncomingHistory>()
+ .property("credit_account", codecForPaytoURI())
+ .property("incoming_transactions", codecForList(codecForMerchantIncomingBankTransaction()))
+ .build("TalerRevenueApi.MerchantIncomingHistory");
+
+export const codecForMerchantIncomingBankTransaction =
+ (): Codec<TalerRevenueApi.MerchantIncomingBankTransaction> =>
+ buildCodecForObject<TalerRevenueApi.MerchantIncomingBankTransaction>()
+ .property("amount", codecForAmountString())
+ .property("date", codecForTimestamp)
+ .property("debit_account", codecForPaytoURI())
+ .property("exchange_url", codecForURL())
+ .property("row_id", codecForNumber())
+ .property("wtid", codecForString())
+ .build("TalerRevenueApi.MerchantIncomingBankTransaction");
+
+export const codecForTransferResponse =
+ (): Codec<TalerWireGatewayApi.TransferResponse> =>
+ buildCodecForObject<TalerWireGatewayApi.TransferResponse>()
+ .property("row_id", codecForNumber())
+ .property("timestamp", codecForTimestamp)
+ .build("TalerWireGatewayApi.TransferResponse");
+
+export const codecForIncomingHistory =
+ (): Codec<TalerWireGatewayApi.IncomingHistory> =>
+ buildCodecForObject<TalerWireGatewayApi.IncomingHistory>()
+ .property("credit_account", codecForString())
+ .property("incoming_transactions", codecForList(codecForIncomingBankTransaction()))
+ .build("TalerWireGatewayApi.IncomingHistory");
+
+export const codecForIncomingBankTransaction = (): Codec<TalerWireGatewayApi.IncomingBankTransaction> => buildCodecForUnion<TalerWireGatewayApi.IncomingBankTransaction>()
+ .discriminateOn("type")
+ .alternative("RESERVE", codecForIncomingReserveTransaction())
+ .alternative("WAD", codecForIncomingWadTransaction())
+ .build("TalerWireGatewayApi.IncomingBankTransaction");
+
+export const codecForIncomingReserveTransaction =
+ (): Codec<TalerWireGatewayApi.IncomingReserveTransaction> =>
+ buildCodecForObject<TalerWireGatewayApi.IncomingReserveTransaction>()
+ .property("amount", codecForAmountString())
+ .property("date", codecForTimestamp)
+ .property("debit_account", codecForPaytoURI())
+ .property("reserve_pub", codecForString())
+ .property("row_id", codecForNumber())
+ .property("type", codecForConstString("RESERVE"))
+ .build("TalerWireGatewayApi.IncomingReserveTransaction");
+
+export const codecForIncomingWadTransaction =
+ (): Codec<TalerWireGatewayApi.IncomingWadTransaction> =>
+ buildCodecForObject<TalerWireGatewayApi.IncomingWadTransaction>()
+ .property("amount", codecForAmountString())
+ .property("credit_account", codecForPaytoURI())
+ .property("date", codecForTimestamp)
+ .property("debit_account", codecForPaytoURI())
+ .property("origin_exchange_url", codecForURL())
+ .property("row_id", codecForNumber())
+ .property("type", codecForConstString("WAD"))
+ .property("wad_id", codecForString())
+ .build("TalerWireGatewayApi.IncomingWadTransaction");
+
+export const codecForOutgoingHistory =
+ (): Codec<TalerWireGatewayApi.OutgoingHistory> =>
+ buildCodecForObject<TalerWireGatewayApi.OutgoingHistory>()
+ .property("debit_account", codecForString())
+ .property("outgoing_transactions", codecForList(codecForOutgoingBankTransaction()))
+ .build("TalerWireGatewayApi.OutgoingHistory");
+
+export const codecForOutgoingBankTransaction =
+ (): Codec<TalerWireGatewayApi.OutgoingBankTransaction> =>
+ buildCodecForObject<TalerWireGatewayApi.OutgoingBankTransaction>()
+ .property("amount", codecForAmountString())
+ .property("credit_account", codecForPaytoURI())
+ .property("date", codecForTimestamp)
+ .property("exchange_base_url", codecForURL())
+ .property("row_id", codecForNumber())
+ .property("wtid", codecForString())
+ .build("TalerWireGatewayApi.OutgoingBankTransaction");
+
+export const codecForAddIncomingResponse =
+ (): Codec<TalerWireGatewayApi.AddIncomingResponse> =>
+ buildCodecForObject<TalerWireGatewayApi.AddIncomingResponse>()
+ .property("row_id", codecForNumber())
+ .property("timestamp", codecForTimestamp)
+ .build("TalerWireGatewayApi.AddIncomingResponse");
// export const codecFor =
-// (): Codec<TalerCorebankApi.PublicAccountsResponse> =>
-// buildCodecForObject<TalerCorebankApi.PublicAccountsResponse>()
+// (): Codec<TalerWireGatewayApi.PublicAccountsResponse> =>
+// buildCodecForObject<TalerWireGatewayApi.PublicAccountsResponse>()
// .property("", codecForString())
-// .build("TalerCorebankApi.PublicAccountsResponse");
+// .build("TalerWireGatewayApi.PublicAccountsResponse");
+
type EmailAddress = string;
type PhoneNumber = string;
type DecimalNumber = string;
+const codecForURL = codecForString
+const codecForLibtoolVersion = codecForString
+const codecForCurrencyName = codecForString
const codecForPaytoURI = codecForString
const codecForTalerWithdrawalURI = codecForString
const codecForDecimalNumber = codecForString
@@ -319,7 +517,289 @@ enum TanChannel {
FILE = "file"
}
+export namespace TalerWireGatewayApi {
+
+ export interface TransferResponse {
+
+ // Timestamp that indicates when the wire transfer will be executed.
+ // In cases where the wire transfer gateway is unable to know when
+ // the wire transfer will be executed, the time at which the request
+ // has been received and stored will be returned.
+ // The purpose of this field is for debugging (humans trying to find
+ // the transaction) as well as for taxation (determining which
+ // time period a transaction belongs to).
+ timestamp: Timestamp;
+
+ // Opaque ID of the transaction that the bank has made.
+ row_id: SafeUint64;
+ }
+
+ export interface TransferRequest {
+ // Nonce to make the request idempotent. Requests with the same
+ // transaction_uid that differ in any of the other fields
+ // are rejected.
+ request_uid: HashCode;
+
+ // Amount to transfer.
+ amount: Amount;
+
+ // Base URL of the exchange. Shall be included by the bank gateway
+ // in the appropriate section of the wire transfer details.
+ exchange_base_url: string;
+
+ // Wire transfer identifier chosen by the exchange,
+ // used by the merchant to identify the Taler order(s)
+ // associated with this wire transfer.
+ wtid: ShortHashCode;
+
+ // The recipient's account identifier as a payto URI.
+ credit_account: string;
+ }
+
+ export interface IncomingHistory {
+
+ // Array of incoming transactions.
+ incoming_transactions: IncomingBankTransaction[];
+
+ // Payto URI to identify the receiver of funds.
+ // This must be one of the exchange's bank accounts.
+ // Credit account is shared by all incoming transactions
+ // as per the nature of the request.
+ credit_account: string;
+
+ }
+
+ // Union discriminated by the "type" field.
+ export type IncomingBankTransaction =
+ | IncomingReserveTransaction
+ | IncomingWadTransaction;
+
+ export interface IncomingReserveTransaction {
+ type: "RESERVE";
+
+ // Opaque identifier of the returned record.
+ row_id: SafeUint64;
+
+ // Date of the transaction.
+ date: Timestamp;
+
+ // Amount transferred.
+ amount: Amount;
+
+ // Payto URI to identify the sender of funds.
+ debit_account: string;
+
+ // The reserve public key extracted from the transaction details.
+ reserve_pub: EddsaPublicKey;
+
+ }
+
+ export interface IncomingWadTransaction {
+ type: "WAD";
+
+ // Opaque identifier of the returned record.
+ row_id: SafeUint64;
+
+ // Date of the transaction.
+ date: Timestamp;
+
+ // Amount transferred.
+ amount: Amount;
+
+ // Payto URI to identify the receiver of funds.
+ // This must be one of the exchange's bank accounts.
+ credit_account: string;
+
+ // Payto URI to identify the sender of funds.
+ debit_account: string;
+
+ // Base URL of the exchange that originated the wad.
+ origin_exchange_url: string;
+
+ // The reserve public key extracted from the transaction details.
+ wad_id: WadId;
+ }
+
+
+ export interface OutgoingHistory {
+
+ // Array of outgoing transactions.
+ outgoing_transactions: OutgoingBankTransaction[];
+
+ // Payto URI to identify the sender of funds.
+ // This must be one of the exchange's bank accounts.
+ // Credit account is shared by all incoming transactions
+ // as per the nature of the request.
+ debit_account: string;
+
+ }
+
+ export interface OutgoingBankTransaction {
+
+ // Opaque identifier of the returned record.
+ row_id: SafeUint64;
+
+ // Date of the transaction.
+ date: Timestamp;
+
+ // Amount transferred.
+ amount: Amount;
+
+ // Payto URI to identify the receiver of funds.
+ credit_account: string;
+
+ // The wire transfer ID in the outgoing transaction.
+ wtid: ShortHashCode;
+
+ // Base URL of the exchange.
+ exchange_base_url: string;
+ }
+
+ export interface AddIncomingRequest {
+ // Amount to transfer.
+ amount: Amount;
+
+ // Reserve public key that is included in the wire transfer details
+ // to identify the reserve that is being topped up.
+ reserve_pub: EddsaPublicKey;
+
+ // Account (as payto URI) that makes the wire transfer to the exchange.
+ // Usually this account must be created by the test harness before this API is
+ // used. An exception is the "exchange-fakebank", where any debit account can be
+ // specified, as it is automatically created.
+ debit_account: string;
+ }
+
+ export interface AddIncomingResponse {
+
+ // Timestamp that indicates when the wire transfer will be executed.
+ // In cases where the wire transfer gateway is unable to know when
+ // the wire transfer will be executed, the time at which the request
+ // has been received and stored will be returned.
+ // The purpose of this field is for debugging (humans trying to find
+ // the transaction) as well as for taxation (determining which
+ // time period a transaction belongs to).
+ timestamp: Timestamp;
+
+ // Opaque ID of the transaction that the bank has made.
+ row_id: SafeUint64;
+ }
+
+
+
+}
+
+export namespace TalerRevenueApi {
+ export interface MerchantIncomingHistory {
+
+ // Array of incoming transactions.
+ incoming_transactions: MerchantIncomingBankTransaction[];
+
+ // Payto URI to identify the receiver of funds.
+ // This must be one of the merchant's bank accounts.
+ // Credit account is shared by all incoming transactions
+ // as per the nature of the request.
+ credit_account: string;
+
+ }
+ export interface MerchantIncomingBankTransaction {
+
+ // Opaque identifier of the returned record.
+ row_id: SafeUint64;
+
+ // Date of the transaction.
+ date: Timestamp;
+
+ // Amount transferred.
+ amount: Amount;
+
+ // Payto URI to identify the sender of funds.
+ debit_account: string;
+
+ // Base URL of the exchange where the transfer originated form.
+ exchange_url: string;
+
+ // The wire transfer identifier.
+ wtid: WireTransferIdentifierRawP;
+ }
+}
+
+export namespace TalerBankIntegrationApi {
+ 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 {
+ // Indicates whether the withdrawal was aborted.
+ aborted: boolean;
+
+ // Has the wallet selected parameters for the withdrawal operation
+ // (exchange and reserve public key) and successfully sent it
+ // to the bank?
+ selection_done: boolean;
+
+ // The transfer has been confirmed and registered by the bank.
+ // Does not guarantee that the funds have arrived at the exchange already.
+ transfer_done: boolean;
+
+ // Amount that will be withdrawn with this operation
+ // (raw amount without fee considerations).
+ amount: Amount;
+
+ // Bank account of the customer that is withdrawing, as a
+ // payto URI.
+ sender_wire?: string;
+
+ // Suggestion for an exchange given by the bank.
+ suggested_exchange?: string;
+
+ // URL that the user needs to navigate to in order to
+ // complete some final confirmation (e.g. 2FA).
+ // It may contain withdrawal operation id
+ confirm_transfer_url?: string;
+
+ // Wire transfer types supported by the bank.
+ wire_types: string[];
+ }
+
+ export interface BankWithdrawalOperationPostRequest {
+
+ // Reserve public key.
+ reserve_pub: string;
+
+ // Payto address of the exchange selected for the withdrawal.
+ selected_exchange: string;
+ }
+
+ export interface BankWithdrawalOperationPostResponse {
+
+ // The transfer has been confirmed and registered by the bank.
+ // Does not guarantee that the funds have arrived at the exchange already.
+ transfer_done: boolean;
+
+ // URL that the user needs to navigate to in order to
+ // complete some final confirmation (e.g. 2FA).
+ //
+ // Only applicable when transfer_done is false.
+ // It may contain withdrawal operation id
+ confirm_transfer_url?: string;
+ }
+
+
+}
export namespace TalerCorebankApi {
export interface Config {
@@ -648,21 +1128,21 @@ export namespace TalerCorebankApi {
// 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{
+
+ export enum MonitorTimeframeParam {
hour, day, month, year, decade,
}
-
+
export interface MonitorResponse {
// This number identifies how many cashin operations
diff --git a/packages/taler-util/src/http-client/utils.ts b/packages/taler-util/src/http-client/utils.ts
@@ -31,9 +31,10 @@ export function addPaginationParams(url: URL, pagination?: PaginationParams) {
if (pagination.offset) {
url.searchParams.set("start", pagination.offset)
}
- if (pagination.limit) {
- url.searchParams.set("delta", String(pagination.limit))
- }
+ const order = !pagination || pagination.order === "asc" ? 1 : -1
+ const limit = !pagination || !pagination.limit || pagination.limit === 0 ? 5 : Math.abs(pagination.limit)
+ //always send delta
+ url.searchParams.set("delta", String(order * limit))
}
export type UserAndPassword = {
@@ -53,10 +54,15 @@ export type PaginationParams = {
offset?: string,
/**
* max number of element in the result response
+ * always greater than 0
*/
limit?: number,
/**
* milliseconds the server should wait for at least one result to be shown
*/
timoutMs?: number,
+ /**
+ * order
+ */
+ order: "asc" | "dec"
}