/*
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
*/
import {
HttpStatusCode,
LibtoolVersion,
TalerErrorCode,
codecForTalerErrorDetail
} from "@gnu-taler/taler-util";
import {
HttpRequestLibrary,
createPlatformHttpLib
} from "@gnu-taler/taler-util/http";
import { FailCasesByMethod, ResultByMethod, opEmptySuccess, opFixedSuccess, opKnownFailure, opSuccess, opUnknownFailure } from "../operation.js";
import { TalerAuthenticationHttpClient } from "./authentication.js";
import { TalerBankConversionHttpClient } from "./bank-conversion.js";
import { TalerBankIntegrationHttpClient } from "./bank-integration.js";
import { TalerRevenueHttpClient } from "./bank-revenue.js";
import { TalerWireGatewayHttpClient } from "./bank-wire.js";
import { AccessToken, PaginationParams, TalerCorebankApi, UserAndToken, WithdrawalOperationStatus, codecForAccountData, codecForBankAccountCreateWithdrawalResponse, codecForBankAccountTransactionInfo, codecForBankAccountTransactionsResponse, codecForCashoutPending, codecForCashoutStatusResponse, codecForCashouts, codecForCoreBankConfig, codecForCreateTransactionResponse, codecForGlobalCashouts, codecForListBankAccountsResponse, codecForMonitorResponse, codecForPublicAccountsResponse, codecForRegisterAccountResponse, codecForWithdrawalPublicInfo } from "./types.js";
import { addPaginationParams, makeBearerTokenAuthHeader } from "./utils.js";
export type TalerCoreBankResultByMethod = ResultByMethod
export type TalerCoreBankErrorsByMethod = FailCasesByMethod
/**
* Protocol version spoken with the bank.
*
* Uses libtool's current:revision:age versioning.
*/
export class TalerCoreBankHttpClient {
public readonly PROTOCOL_VERSION = "0:0:0";
httpLib: HttpRequestLibrary;
constructor(
readonly baseUrl: string,
httpClient?: HttpRequestLibrary,
) {
this.httpLib = httpClient ?? createPlatformHttpLib();
}
isCompatible(version: string): boolean {
const compare = LibtoolVersion.compare(this.PROTOCOL_VERSION, version)
return compare?.compatible ?? false
}
/**
* https://docs.taler.net/core/api-corebank.html#config
*
*/
async getConfig() {
const url = new URL(`config`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "GET"
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForCoreBankConfig())
default: return opUnknownFailure(resp, await resp.text())
}
}
//
// ACCOUNTS
//
/**
* https://docs.taler.net/core/api-corebank.html#post--accounts
*
*/
async createAccount(auth: AccessToken, body: TalerCorebankApi.RegisterAccountRequest) {
const url = new URL(`accounts`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "POST",
body,
headers: {
Authorization: makeBearerTokenAuthHeader(auth)
},
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForRegisterAccountResponse())
case HttpStatusCode.BadRequest: return opKnownFailure("invalid-phone-or-email", resp);
case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp);
case HttpStatusCode.Conflict: {
const body = await resp.json()
const details = codecForTalerErrorDetail().decode(body)
switch (details.code) {
case TalerErrorCode.BANK_REGISTER_USERNAME_REUSE: return opKnownFailure("username-already-exists", resp);
case TalerErrorCode.BANK_REGISTER_PAYTO_URI_REUSE: return opKnownFailure("payto-already-exists", resp);
case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownFailure("insufficient-funds", resp);
case TalerErrorCode.BANK_RESERVED_USERNAME_CONFLICT: return opKnownFailure("username-reserved", resp);
case TalerErrorCode.BANK_NON_ADMIN_PATCH_DEBT_LIMIT: return opKnownFailure("user-cant-set-debt", resp);
default: return opUnknownFailure(resp, body)
}
}
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#delete--accounts-$USERNAME
*
*/
async deleteAccount(auth: UserAndToken) {
const url = new URL(`accounts/${auth.username}`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "DELETE",
headers: {
Authorization: makeBearerTokenAuthHeader(auth.token)
},
});
switch (resp.status) {
case HttpStatusCode.NoContent: return opEmptySuccess()
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp);
case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp);
case HttpStatusCode.Conflict: {
const body = await resp.json()
const details = codecForTalerErrorDetail().decode(body)
switch (details.code) {
case TalerErrorCode.BANK_RESERVED_USERNAME_CONFLICT: return opKnownFailure("username-reserved", resp);
case TalerErrorCode.BANK_ACCOUNT_BALANCE_NOT_ZERO: return opKnownFailure("balance-not-zero", resp);
default: return opUnknownFailure(resp, body)
}
}
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#patch--accounts-$USERNAME
*
*/
async updateAccount(auth: UserAndToken, body: TalerCorebankApi.AccountReconfiguration) {
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)
},
});
switch (resp.status) {
case HttpStatusCode.NoContent: return opEmptySuccess()
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp);
case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp);
case HttpStatusCode.Conflict: {
const body = await resp.json()
const details = codecForTalerErrorDetail().decode(body)
switch (details.code) {
case TalerErrorCode.BANK_PATCH_ADMIN_EXCHANGE: return opKnownFailure("admin-cant-be-exchange", resp);
case TalerErrorCode.BANK_NON_ADMIN_PATCH_LEGAL_NAME: return opKnownFailure("user-cant-change-name", resp);
case TalerErrorCode.BANK_NON_ADMIN_PATCH_DEBT_LIMIT: return opKnownFailure("user-cant-change-debt", resp);
default: return opUnknownFailure(resp, body)
}
}
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#patch--accounts-$USERNAME-auth
*
*/
async updatePassword(auth: UserAndToken, body: TalerCorebankApi.AccountPasswordChange) {
const url = new URL(`accounts/${auth.username}/auth`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "PATCH",
body,
headers: {
Authorization: makeBearerTokenAuthHeader(auth.token)
},
});
switch (resp.status) {
case HttpStatusCode.NoContent: return opEmptySuccess()
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp);
case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp);
case HttpStatusCode.Conflict: {
const body = await resp.json()
const details = codecForTalerErrorDetail().decode(body)
switch (details.code) {
case TalerErrorCode.BANK_NON_ADMIN_PATCH_MISSING_OLD_PASSWORD: return opKnownFailure("user-require-old-password", resp);
case TalerErrorCode.BANK_PATCH_BAD_OLD_PASSWORD: return opKnownFailure("wrong-old-password", resp);
default: return opUnknownFailure(resp, body)
}
}
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#get--public-accounts
*
*/
async getPublicAccounts(filter: { account?: string } = {}, pagination?: PaginationParams) {
const url = new URL(`public-accounts`, this.baseUrl);
addPaginationParams(url, pagination)
if (filter.account !== undefined) {
url.searchParams.set("filter_name", filter.account)
}
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForPublicAccountsResponse())
case HttpStatusCode.NoContent: return opFixedSuccess({ public_accounts: [] })
case HttpStatusCode.NotFound: return opFixedSuccess({ public_accounts: [] })
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#get--accounts
*
*/
async getAccounts(auth: AccessToken, filter: { account?: string } = {}, pagination?: PaginationParams) {
const url = new URL(`accounts`, this.baseUrl);
addPaginationParams(url, pagination)
if (filter.account !== undefined) {
url.searchParams.set("filter_name", filter.account)
}
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
headers: {
Authorization: makeBearerTokenAuthHeader(auth)
},
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForListBankAccountsResponse())
case HttpStatusCode.NoContent: return opFixedSuccess({ accounts: [] })
case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME
*
*/
async getAccount(auth: UserAndToken) {
const url = new URL(`accounts/${auth.username}`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
headers: {
Authorization: makeBearerTokenAuthHeader(auth.token)
},
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForAccountData())
case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp);
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
//
// TRANSACTIONS
//
/**
* https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME-transactions
*
*/
async getTransactions(auth: UserAndToken, pagination?: PaginationParams) {
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)
},
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForBankAccountTransactionsResponse())
case HttpStatusCode.NoContent: return opFixedSuccess({ transactions: [] })
case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp);
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME-transactions-$TRANSACTION_ID
*
*/
async getTransactionById(auth: UserAndToken, txid: number) {
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)
},
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForBankAccountTransactionInfo())
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp);
case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-transactions
*
*/
async createTransaction(auth: UserAndToken, body: TalerCorebankApi.CreateTransactionRequest) {
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,
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForCreateTransactionResponse())
case HttpStatusCode.BadRequest: return opKnownFailure("invalid-input", resp);
case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp);
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp);
case HttpStatusCode.Conflict: {
const body = await resp.json()
const details = codecForTalerErrorDetail().decode(body)
switch (details.code) {
case TalerErrorCode.BANK_SAME_ACCOUNT: return opKnownFailure("creditor-same", resp);
case TalerErrorCode.BANK_UNKNOWN_CREDITOR: return opKnownFailure("creditor-not-found", resp);
case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownFailure("insufficient-funds", resp);
default: return opUnknownFailure(resp, body)
}
}
default: return opUnknownFailure(resp, await resp.text())
}
}
//
// WITHDRAWALS
//
/**
* https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-withdrawals
*
*/
async createWithdrawal(auth: UserAndToken, body: TalerCorebankApi.BankAccountCreateWithdrawalRequest) {
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,
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForBankAccountCreateWithdrawalResponse())
case HttpStatusCode.NotFound: return opKnownFailure("account-not-found", resp);
case HttpStatusCode.Conflict: return opKnownFailure("insufficient-funds", resp);
case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-withdrawals-$WITHDRAWAL_ID-abort
*
*/
async abortWithdrawalById(auth: UserAndToken, wid: string) {
const url = new URL(`accounts/${auth.username}/withdrawals/${wid}/abort`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "POST",
headers: {
Authorization: makeBearerTokenAuthHeader(auth.token)
},
});
switch (resp.status) {
case HttpStatusCode.NoContent: return opEmptySuccess()
//FIXME: missing in docs
case HttpStatusCode.BadRequest: return opKnownFailure("invalid-id", resp)
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp)
case HttpStatusCode.Conflict: return opKnownFailure("previously-confirmed", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-withdrawals-$WITHDRAWAL_ID-confirm
*
*/
async confirmWithdrawalById(auth: UserAndToken, wid: string) {
const url = new URL(`accounts/${auth.username}/withdrawals/${wid}/confirm`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "POST",
headers: {
Authorization: makeBearerTokenAuthHeader(auth.token)
},
});
switch (resp.status) {
case HttpStatusCode.NoContent: return opEmptySuccess()
//FIXME: missing in docs
case HttpStatusCode.BadRequest: return opKnownFailure("invalid-id", resp)
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp)
case HttpStatusCode.Conflict: {
const body = await resp.json()
const details = codecForTalerErrorDetail().decode(body)
switch (details.code) {
case TalerErrorCode.BANK_CONFIRM_ABORT_CONFLICT: return opKnownFailure("previously-aborted", resp);
case TalerErrorCode.BANK_CONFIRM_INCOMPLETE: return opKnownFailure("no-exchange-or-reserve-selected", resp);
case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownFailure("insufficient-funds", resp);
default: return opUnknownFailure(resp, body)
}
}
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#get--withdrawals-$WITHDRAWAL_ID
*
*/
async getWithdrawalById(wid: string, wait?: {
old_state?: WithdrawalOperationStatus,
timeoutMs: number
}) {
const url = new URL(`withdrawals/${wid}`, this.baseUrl);
if (wait) {
url.searchParams.set("long_poll_ms", String(wait.timeoutMs))
url.searchParams.set("old_state", !wait.old_state ? "pending" : wait.old_state)
}
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForWithdrawalPublicInfo())
//FIXME: missing in docs
case HttpStatusCode.BadRequest: return opKnownFailure("invalid-id", resp)
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp)
default: return opUnknownFailure(resp, await resp.text())
}
}
//
// CASHOUTS
//
/**
* https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts
*
*/
async createCashout(auth: UserAndToken, body: TalerCorebankApi.CashoutRequest) {
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,
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForCashoutPending())
case HttpStatusCode.NotFound: return opKnownFailure("account-not-found", resp)
case HttpStatusCode.Conflict: {
const body = await resp.json()
const details = codecForTalerErrorDetail().decode(body)
switch (details.code) {
case TalerErrorCode.BANK_TRANSFER_REQUEST_UID_REUSED: return opKnownFailure("request-already-used", resp);
case TalerErrorCode.BANK_BAD_CONVERSION: return opKnownFailure("incorrect-exchange-rate", resp);
case TalerErrorCode.BANK_MISSING_TAN_INFO: return opKnownFailure("no-contact-info", resp);
case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownFailure("no-enough-balance", resp);
default: return opUnknownFailure(resp, body)
}
}
case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp);
case HttpStatusCode.BadGateway: return opKnownFailure("tan-failed", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts-$CASHOUT_ID-abort
*
*/
async abortCashoutById(auth: UserAndToken, cid: number) {
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)
},
});
switch (resp.status) {
case HttpStatusCode.NoContent: return opEmptySuccess()
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp);
case HttpStatusCode.Conflict: return opKnownFailure("already-confirmed", resp);
case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts-$CASHOUT_ID-confirm
*
*/
async confirmCashoutById(auth: UserAndToken, cid: number, body: TalerCorebankApi.CashoutConfirmRequest) {
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,
});
switch (resp.status) {
case HttpStatusCode.NoContent: return opEmptySuccess()
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp);
// case HttpStatusCode.Forbidden: return opKnownFailure("wrong-tan-or-credential", resp);
case HttpStatusCode.Conflict: {
const body = await resp.json()
const details = codecForTalerErrorDetail().decode(body)
switch (details.code) {
case TalerErrorCode.BANK_CONFIRM_ABORT_CONFLICT: return opKnownFailure("already-aborted", resp);
case TalerErrorCode.BANK_CONFIRM_INCOMPLETE: return opKnownFailure("no-cashout-payto", resp);
case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownFailure("no-enough-balance", resp);
case TalerErrorCode.BANK_BAD_CONVERSION: return opKnownFailure("incorrect-exchange-rate", resp);
case TalerErrorCode.BANK_TAN_CHALLENGE_FAILED: return opKnownFailure("invalid-code", resp);
default: return opUnknownFailure(resp, body)
}
}
case HttpStatusCode.TooManyRequests: return opKnownFailure("too-many-attempts", resp);
case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME-cashouts-$CASHOUT_ID
*
*/
async getCashoutById(auth: UserAndToken, cid: number) {
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)
},
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForCashoutStatusResponse())
case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp);
case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME-cashouts
*
*/
async getAccountCashouts(auth: UserAndToken, pagination?: PaginationParams) {
const url = new URL(`accounts/${auth.username}/cashouts`, this.baseUrl);
addPaginationParams(url, pagination)
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
headers: {
Authorization: makeBearerTokenAuthHeader(auth.token)
},
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForCashouts())
case HttpStatusCode.NoContent: return opFixedSuccess({ cashouts: [] });
case HttpStatusCode.NotFound: return opKnownFailure("account-not-found", resp);;
case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
* https://docs.taler.net/core/api-corebank.html#get--cashouts
*
*/
async getGlobalCashouts(auth: AccessToken, pagination?: PaginationParams) {
const url = new URL(`cashouts`, this.baseUrl);
addPaginationParams(url, pagination)
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
headers: {
Authorization: makeBearerTokenAuthHeader(auth)
},
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForGlobalCashouts())
case HttpStatusCode.NoContent: return opFixedSuccess({ cashouts: [] });
case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
//
// MONITOR
//
/**
* https://docs.taler.net/core/api-corebank.html#get--monitor
*
*/
async getMonitor(auth: AccessToken, params: { timeframe?: TalerCorebankApi.MonitorTimeframeParam, which?: number } = {}) {
const url = new URL(`monitor`, this.baseUrl);
if (params.timeframe) {
url.searchParams.set("timeframe", TalerCorebankApi.MonitorTimeframeParam[params.timeframe])
}
if (params.which) {
url.searchParams.set("which", String(params.which))
}
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
headers: {
Authorization: makeBearerTokenAuthHeader(auth)
},
});
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForMonitorResponse())
case HttpStatusCode.BadRequest: return opKnownFailure("invalid-input", resp);
case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp);
//FIXME remove when server is updated
//FIXME: should be 404 ?
case HttpStatusCode.ServiceUnavailable: return opKnownFailure("monitor-not-supported", resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
//
// 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,)
}
/**
* https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-token
*
*/
getAuthenticationAPI(username: string): TalerAuthenticationHttpClient {
const url = new URL(`accounts/${username}/`, this.baseUrl);
return new TalerAuthenticationHttpClient(url.href, username, this.httpLib,)
}
/**
* https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-token
*
*/
getConversionInfoAPI(): TalerBankConversionHttpClient {
const url = new URL(`conversion-info/`, this.baseUrl);
return new TalerBankConversionHttpClient(url.href, this.httpLib)
}
}