diff options
Diffstat (limited to 'packages/taler-util/src/http-client/bank-core.ts')
-rw-r--r-- | packages/taler-util/src/http-client/bank-core.ts | 489 |
1 files changed, 489 insertions, 0 deletions
diff --git a/packages/taler-util/src/http-client/bank-core.ts b/packages/taler-util/src/http-client/bank-core.ts new file mode 100644 index 000000000..c77f9ddda --- /dev/null +++ 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,) + } + +} + |