wip: http-client
This commit is contained in:
parent
8ae4ad9342
commit
36b7918a79
523
packages/taler-util/src/http-client/core-bank.ts
Normal file
523
packages/taler-util/src/http-client/core-bank.ts
Normal file
@ -0,0 +1,523 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
703
packages/taler-util/src/http-client/types.ts
Normal file
703
packages/taler-util/src/http-client/types.ts
Normal file
@ -0,0 +1,703 @@
|
||||
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 { codecForTimestamp } from "../time.js";
|
||||
|
||||
|
||||
type HashCode = string;
|
||||
type EddsaPublicKey = string;
|
||||
type EddsaSignature = string;
|
||||
type WireTransferIdentifierRawP = string;
|
||||
type RelativeTime = {
|
||||
d_us: number | "forever"
|
||||
};
|
||||
type ImageDataUrl = string;
|
||||
|
||||
interface WithId {
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface Timestamp {
|
||||
// Milliseconds since epoch, or the special
|
||||
// value "forever" to represent an event that will
|
||||
// never happen.
|
||||
t_s: number | "never";
|
||||
}
|
||||
interface Duration {
|
||||
d_us: number | "forever";
|
||||
}
|
||||
|
||||
interface WithId {
|
||||
id: string;
|
||||
}
|
||||
|
||||
type UUID = string;
|
||||
type Integer = number;
|
||||
|
||||
type Amount = string;
|
||||
|
||||
|
||||
export interface LoginToken {
|
||||
token: AccessToken,
|
||||
expiration: Timestamp,
|
||||
}
|
||||
// token used to get loginToken
|
||||
// must forget after used
|
||||
declare const __ac_token: unique symbol;
|
||||
export type AccessToken = string & {
|
||||
[__ac_token]: true;
|
||||
};
|
||||
|
||||
export namespace TalerAuthentication {
|
||||
|
||||
export interface TokenRequest {
|
||||
// Service-defined scope for the token.
|
||||
// Typical scopes would be "readonly" or "readwrite".
|
||||
scope: string;
|
||||
|
||||
// Server may impose its own upper bound
|
||||
// on the token validity duration
|
||||
duration?: RelativeTime;
|
||||
|
||||
// Is the token refreshable into a new token during its
|
||||
// validity?
|
||||
// Refreshable tokens effectively provide indefinite
|
||||
// access if they are refreshed in time.
|
||||
refreshable?: boolean;
|
||||
}
|
||||
|
||||
export interface TokenSuccessResponse {
|
||||
// Expiration determined by the server.
|
||||
// Can be based on the token_duration
|
||||
// from the request, but ultimately the
|
||||
// server decides the expiration.
|
||||
expiration: Timestamp;
|
||||
|
||||
// Opque access token.
|
||||
access_token: AccessToken;
|
||||
}
|
||||
}
|
||||
|
||||
interface CurrencySpecification {
|
||||
|
||||
// Name of the currency.
|
||||
name: string;
|
||||
|
||||
// Decimal separator for fractional digits.
|
||||
decimal_separator: string;
|
||||
|
||||
// how many digits the user may enter after the decimal_separator
|
||||
num_fractional_input_digits: Integer;
|
||||
|
||||
// Number of fractional digits to render in normal font and size.
|
||||
num_fractional_normal_digits: Integer;
|
||||
|
||||
// Number of fractional digits to render always, if needed by
|
||||
// padding with zeros.
|
||||
num_fractional_trailing_zero_digits: Integer;
|
||||
|
||||
// Whether the currency name should be rendered before (true) or
|
||||
// after (false) the numeric value
|
||||
is_currency_name_leading: boolean;
|
||||
|
||||
// map of powers of 10 to alternative currency names / symbols, must
|
||||
// always have an entry under "0" that defines the base name,
|
||||
// e.g. "0 => €" or "3 => k€". For BTC, would be "0 => BTC, -3 => mBTC".
|
||||
// Communicates the currency symbol to be used.
|
||||
alt_unit_names: { [log10: string]: string };
|
||||
}
|
||||
|
||||
export const codecForAccessToken = codecForString as () => Codec<AccessToken>;
|
||||
export const codecForTokenSuccessResponse =
|
||||
(): Codec<TalerAuthentication.TokenSuccessResponse> =>
|
||||
buildCodecForObject<TalerAuthentication.TokenSuccessResponse>()
|
||||
.property("access_token", codecForAccessToken())
|
||||
.property("expiration", codecForTimestamp)
|
||||
.build("TalerAuthentication.TokenSuccessResponse")
|
||||
|
||||
export const codecForCurrencySpecificiation =
|
||||
(): Codec<CurrencySpecification> =>
|
||||
buildCodecForObject<CurrencySpecification>()
|
||||
.property("name", codecForString())
|
||||
.property("decimal_separator", codecForString())
|
||||
.property("num_fractional_input_digits", codecForNumber())
|
||||
.property("num_fractional_normal_digits", codecForNumber())
|
||||
.property("num_fractional_trailing_zero_digits", codecForNumber())
|
||||
.property("is_currency_name_leading", codecForBoolean())
|
||||
.property("alt_unit_names", codecForMap(codecForString()))
|
||||
.build("CurrencySpecification")
|
||||
|
||||
export const codecForCoreBankConfig =
|
||||
(): Codec<TalerCorebankApi.Config> =>
|
||||
buildCodecForObject<TalerCorebankApi.Config>()
|
||||
.property("name", codecForString())
|
||||
.property("version", codecForString())
|
||||
.property("have_cashout", codecOptional(codecForBoolean()))
|
||||
.property("currency", codecForCurrencySpecificiation())
|
||||
.property("fiat_currency", codecOptional(codecForCurrencySpecificiation()))
|
||||
.build("TalerCorebankApi.Config")
|
||||
|
||||
const codecForBalance = (): Codec<TalerCorebankApi.Balance> =>
|
||||
buildCodecForObject<TalerCorebankApi.Balance>()
|
||||
.property("amount", codecForAmountString())
|
||||
.property("credit_debit_indicator", codecForEither(codecForConstString("credit"), codecForConstString("debit")))
|
||||
.build("TalerCorebankApi.Balance")
|
||||
|
||||
const codecForPublicAccount = (): Codec<TalerCorebankApi.PublicAccount> =>
|
||||
buildCodecForObject<TalerCorebankApi.PublicAccount>()
|
||||
.property("account_name", codecForString())
|
||||
.property("balance", codecForBalance())
|
||||
.property("payto_uri", codecForPaytoURI())
|
||||
.build("TalerCorebankApi.PublicAccount")
|
||||
|
||||
export const codecForPublicAccountsResponse =
|
||||
(): Codec<TalerCorebankApi.PublicAccountsResponse> =>
|
||||
buildCodecForObject<TalerCorebankApi.PublicAccountsResponse>()
|
||||
.property("public_accounts", codecForList(codecForPublicAccount()))
|
||||
.build("TalerCorebankApi.PublicAccountsResponse")
|
||||
|
||||
|
||||
export const codecForAccountMinimalData =
|
||||
(): Codec<TalerCorebankApi.AccountMinimalData> =>
|
||||
buildCodecForObject<TalerCorebankApi.AccountMinimalData>()
|
||||
.property("balance", codecForBalance())
|
||||
.property("debit_threshold", codecForAmountString())
|
||||
.property("name", codecForString())
|
||||
.property("username", codecForString())
|
||||
.build("TalerCorebankApi.AccountMinimalData")
|
||||
|
||||
export const codecForListBankAccountsResponse =
|
||||
(): Codec<TalerCorebankApi.ListBankAccountsResponse> =>
|
||||
buildCodecForObject<TalerCorebankApi.ListBankAccountsResponse>()
|
||||
.property("accounts", codecForList(codecForAccountMinimalData()))
|
||||
.build("TalerCorebankApi.ListBankAccountsResponse")
|
||||
|
||||
export const codecForAccountData =
|
||||
(): Codec<TalerCorebankApi.AccountData> =>
|
||||
buildCodecForObject<TalerCorebankApi.AccountData>()
|
||||
.property("name", codecForString())
|
||||
.property("balance", codecForBalance())
|
||||
.property("payto_uri", codecForPaytoURI())
|
||||
.property("debit_threshold", codecForAmountString())
|
||||
.property("contact_data", codecOptional(codecForChallengeContactData()))
|
||||
.property("cashout_payto_uri", codecOptional(codecForPaytoURI()))
|
||||
.build("TalerCorebankApi.AccountData")
|
||||
|
||||
|
||||
export const codecForChallengeContactData =
|
||||
(): Codec<TalerCorebankApi.ChallengeContactData> =>
|
||||
buildCodecForObject<TalerCorebankApi.ChallengeContactData>()
|
||||
.property("email", codecOptional(codecForString()))
|
||||
.property("phone", codecOptional(codecForString()))
|
||||
.build("TalerCorebankApi.ChallengeContactData")
|
||||
|
||||
export const codecForBankAccountTransactionsResponse =
|
||||
(): Codec<TalerCorebankApi.BankAccountTransactionsResponse> =>
|
||||
buildCodecForObject<TalerCorebankApi.BankAccountTransactionsResponse>()
|
||||
.property("transactions", codecForList(codecForBankAccountTransactionInfo()))
|
||||
.build("TalerCorebankApi.BankAccountTransactionsResponse");
|
||||
|
||||
export const codecForBankAccountTransactionInfo =
|
||||
(): Codec<TalerCorebankApi.BankAccountTransactionInfo> =>
|
||||
buildCodecForObject<TalerCorebankApi.BankAccountTransactionInfo>()
|
||||
.property("amount", codecForAmountString())
|
||||
.property("creditor_payto_uri", codecForPaytoURI())
|
||||
.property("date", codecForTimestamp)
|
||||
.property("debtor_payto_uri", codecForPaytoURI())
|
||||
.property("direction", codecForEither(codecForConstString("debit"), codecForConstString("credit")))
|
||||
.property("row_id", codecForNumber())
|
||||
.property("subject", codecForString())
|
||||
.build("TalerCorebankApi.BankAccountTransactionInfo");
|
||||
|
||||
export const codecForBankAccountCreateWithdrawalResponse =
|
||||
(): Codec<TalerCorebankApi.BankAccountCreateWithdrawalResponse> =>
|
||||
buildCodecForObject<TalerCorebankApi.BankAccountCreateWithdrawalResponse>()
|
||||
.property("taler_withdraw_uri", codecForTalerWithdrawalURI())
|
||||
.property("withdrawal_id", codecForString())
|
||||
.build("TalerCorebankApi.BankAccountCreateWithdrawalResponse");
|
||||
|
||||
export const codecForBankAccountGetWithdrawalResponse =
|
||||
(): Codec<TalerCorebankApi.BankAccountGetWithdrawalResponse> =>
|
||||
buildCodecForObject<TalerCorebankApi.BankAccountGetWithdrawalResponse>()
|
||||
.property("aborted", codecForBoolean())
|
||||
.property("amount", codecForAmountString())
|
||||
.property("confirmation_done", codecForBoolean())
|
||||
.property("selected_exchange_account", codecOptional(codecForString()))
|
||||
.property("selected_reserve_pub", codecOptional(codecForString()))
|
||||
.property("selection_done", (codecForBoolean()))
|
||||
.build("TalerCorebankApi.BankAccountGetWithdrawalResponse");
|
||||
|
||||
export const codecForCashoutPending =
|
||||
(): Codec<TalerCorebankApi.CashoutPending> =>
|
||||
buildCodecForObject<TalerCorebankApi.CashoutPending>()
|
||||
.property("cashout_id", codecForString())
|
||||
.build("TalerCorebankApi.CashoutPending");
|
||||
|
||||
export const codecForCashoutConversionResponse =
|
||||
(): Codec<TalerCorebankApi.CashoutConversionResponse> =>
|
||||
buildCodecForObject<TalerCorebankApi.CashoutConversionResponse>()
|
||||
.property("amount_credit", codecForAmountString())
|
||||
.property("amount_debit", codecForAmountString())
|
||||
.build("TalerCorebankApi.CashoutConversionResponse");
|
||||
|
||||
export const codecForCashouts =
|
||||
(): Codec<TalerCorebankApi.Cashouts> =>
|
||||
buildCodecForObject<TalerCorebankApi.Cashouts>()
|
||||
.property("cashouts", codecForList(codecForCashoutInfo()))
|
||||
.build("TalerCorebankApi.Cashouts");
|
||||
|
||||
export const codecForCashoutInfo =
|
||||
(): Codec<TalerCorebankApi.CashoutInfo> =>
|
||||
buildCodecForObject<TalerCorebankApi.CashoutInfo>()
|
||||
.property("cashout_id", codecForString())
|
||||
.property("status", codecForEither(codecForConstString("pending"), codecForConstString("confirmed"),))
|
||||
.build("TalerCorebankApi.CashoutInfo");
|
||||
|
||||
export const codecForGlobalCashouts =
|
||||
(): Codec<TalerCorebankApi.GlobalCashouts> =>
|
||||
buildCodecForObject<TalerCorebankApi.GlobalCashouts>()
|
||||
.property("cashouts", codecForList(codecForGlobalCashoutInfo()))
|
||||
.build("TalerCorebankApi.GlobalCashouts");
|
||||
|
||||
export const codecForGlobalCashoutInfo =
|
||||
(): Codec<TalerCorebankApi.GlobalCashoutInfo> =>
|
||||
buildCodecForObject<TalerCorebankApi.GlobalCashoutInfo>()
|
||||
.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");
|
||||
|
||||
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");
|
||||
|
||||
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");
|
||||
|
||||
// export const codecFor =
|
||||
// (): Codec<TalerCorebankApi.PublicAccountsResponse> =>
|
||||
// buildCodecForObject<TalerCorebankApi.PublicAccountsResponse>()
|
||||
// .property("", codecForString())
|
||||
// .build("TalerCorebankApi.PublicAccountsResponse");
|
||||
|
||||
type EmailAddress = string;
|
||||
type PhoneNumber = string;
|
||||
type DecimalNumber = string;
|
||||
|
||||
const codecForPaytoURI = codecForString
|
||||
const codecForTalerWithdrawalURI = codecForString
|
||||
const codecForDecimalNumber = codecForString
|
||||
|
||||
enum TanChannel {
|
||||
SMS = "sms",
|
||||
EMAIL = "email",
|
||||
FILE = "file"
|
||||
}
|
||||
|
||||
|
||||
export namespace TalerCorebankApi {
|
||||
|
||||
export interface Config {
|
||||
// Name of this API, always "circuit".
|
||||
name: string;
|
||||
// API version in the form $n:$n:$n
|
||||
version: string;
|
||||
|
||||
// If 'true', the server provides local currency
|
||||
// conversion support.
|
||||
// If missing or false, some parts of the API
|
||||
// are not supported and return 404.
|
||||
have_cashout?: boolean;
|
||||
|
||||
// How the bank SPA should render the currency.
|
||||
currency: CurrencySpecification;
|
||||
|
||||
// Fiat currency. That is the currency in which
|
||||
// cash-out operations ultimately wire money.
|
||||
// Only applicable if have_cashout=true.
|
||||
fiat_currency?: CurrencySpecification;
|
||||
}
|
||||
|
||||
export interface BankAccountCreateWithdrawalRequest {
|
||||
// Amount to withdraw.
|
||||
amount: Amount;
|
||||
}
|
||||
export interface BankAccountCreateWithdrawalResponse {
|
||||
// ID of the withdrawal, can be used to view/modify the withdrawal operation.
|
||||
withdrawal_id: string;
|
||||
|
||||
// URI that can be passed to the wallet to initiate the withdrawal.
|
||||
taler_withdraw_uri: string;
|
||||
}
|
||||
export interface BankAccountGetWithdrawalResponse {
|
||||
// Amount that will be withdrawn with this withdrawal operation.
|
||||
amount: Amount;
|
||||
|
||||
// Was the withdrawal aborted?
|
||||
aborted: boolean;
|
||||
|
||||
// Has the withdrawal been confirmed by the bank?
|
||||
// The wire transfer for a withdrawal is only executed once
|
||||
// both confirmation_done is true and selection_done is true.
|
||||
confirmation_done: boolean;
|
||||
|
||||
// Did the wallet select reserve details?
|
||||
selection_done: boolean;
|
||||
|
||||
// Reserve public key selected by the exchange,
|
||||
// only non-null if selection_done is true.
|
||||
selected_reserve_pub: string | undefined;
|
||||
|
||||
// Exchange account selected by the wallet, or by the bank
|
||||
// (with the default exchange) in case the wallet did not provide one
|
||||
// through the Integration API.
|
||||
selected_exchange_account: string | undefined;
|
||||
}
|
||||
|
||||
export interface BankAccountTransactionsResponse {
|
||||
transactions: BankAccountTransactionInfo[];
|
||||
}
|
||||
|
||||
export interface BankAccountTransactionInfo {
|
||||
creditor_payto_uri: string;
|
||||
debtor_payto_uri: string;
|
||||
|
||||
amount: Amount;
|
||||
direction: "debit" | "credit";
|
||||
|
||||
subject: string;
|
||||
|
||||
// Transaction unique ID. Matches
|
||||
// $transaction_id from the URI.
|
||||
row_id: number;
|
||||
date: Timestamp;
|
||||
}
|
||||
|
||||
export interface CreateBankAccountTransactionCreate {
|
||||
// Address in the Payto format of the wire transfer receiver.
|
||||
// It needs at least the 'message' query string parameter.
|
||||
payto_uri: string;
|
||||
|
||||
// Transaction amount (in the $currency:x.y format), optional.
|
||||
// However, when not given, its value must occupy the 'amount'
|
||||
// query string parameter of the 'payto' field. In case it
|
||||
// is given in both places, the paytoUri's takes the precedence.
|
||||
amount?: string;
|
||||
}
|
||||
|
||||
export interface RegisterAccountRequest {
|
||||
// Username
|
||||
username: string;
|
||||
|
||||
// Password.
|
||||
password: string;
|
||||
|
||||
// Legal name of the account owner
|
||||
name: string;
|
||||
|
||||
// Defaults to false.
|
||||
is_public?: boolean;
|
||||
|
||||
// Is this a taler exchange account?
|
||||
// If true:
|
||||
// - incoming transactions to the account that do not
|
||||
// have a valid reserve public key are automatically
|
||||
// - the account provides the taler-wire-gateway-api endpoints
|
||||
// Defaults to false.
|
||||
is_taler_exchange?: boolean;
|
||||
|
||||
// Addresses where to send the TAN for transactions.
|
||||
// Currently only used for cashouts.
|
||||
// If missing, cashouts will fail.
|
||||
// In the future, might be used for other transactions
|
||||
// as well.
|
||||
challenge_contact_data?: ChallengeContactData;
|
||||
|
||||
// 'payto' address pointing a bank account
|
||||
// external to the libeufin-bank.
|
||||
// Payments will be sent to this bank account
|
||||
// when the user wants to convert the local currency
|
||||
// back to fiat currency outside libeufin-bank.
|
||||
cashout_payto_uri?: string;
|
||||
|
||||
// Internal payto URI of this bank account.
|
||||
// Used mostly for testing.
|
||||
internal_payto_uri?: string;
|
||||
}
|
||||
export interface ChallengeContactData {
|
||||
|
||||
// E-Mail address
|
||||
email?: EmailAddress;
|
||||
|
||||
// Phone number.
|
||||
phone?: PhoneNumber;
|
||||
}
|
||||
|
||||
export interface AccountReconfiguration {
|
||||
|
||||
// Addresses where to send the TAN for transactions.
|
||||
// Currently only used for cashouts.
|
||||
// If missing, cashouts will fail.
|
||||
// In the future, might be used for other transactions
|
||||
// as well.
|
||||
challenge_contact_data?: ChallengeContactData;
|
||||
|
||||
// 'payto' address pointing a bank account
|
||||
// external to the libeufin-bank.
|
||||
// Payments will be sent to this bank account
|
||||
// when the user wants to convert the local currency
|
||||
// back to fiat currency outside libeufin-bank.
|
||||
cashout_address?: string;
|
||||
|
||||
// Legal name associated with $username.
|
||||
// When missing, the old name is kept.
|
||||
name?: string;
|
||||
|
||||
// If present, change the is_exchange configuration.
|
||||
// See RegisterAccountRequest
|
||||
is_exchange?: boolean;
|
||||
}
|
||||
|
||||
|
||||
export interface AccountPasswordChange {
|
||||
|
||||
// New password.
|
||||
new_password: string;
|
||||
}
|
||||
|
||||
export interface PublicAccountsResponse {
|
||||
public_accounts: PublicAccount[];
|
||||
}
|
||||
export interface PublicAccount {
|
||||
payto_uri: string;
|
||||
|
||||
balance: Balance;
|
||||
|
||||
// The account name (=username) of the
|
||||
// libeufin-bank account.
|
||||
account_name: string;
|
||||
}
|
||||
|
||||
export interface ListBankAccountsResponse {
|
||||
accounts: AccountMinimalData[];
|
||||
}
|
||||
export interface Balance {
|
||||
amount: Amount;
|
||||
credit_debit_indicator: "credit" | "debit";
|
||||
}
|
||||
export interface AccountMinimalData {
|
||||
// Username
|
||||
username: string;
|
||||
|
||||
// Legal name of the account owner.
|
||||
name: string;
|
||||
|
||||
// current balance of the account
|
||||
balance: Balance;
|
||||
|
||||
// Number indicating the max debit allowed for the requesting user.
|
||||
debit_threshold: Amount;
|
||||
}
|
||||
|
||||
export interface AccountData {
|
||||
// Legal name of the account owner.
|
||||
name: string;
|
||||
|
||||
// Available balance on the account.
|
||||
balance: Balance;
|
||||
|
||||
// payto://-URI of the account.
|
||||
payto_uri: string;
|
||||
|
||||
// Number indicating the max debit allowed for the requesting user.
|
||||
debit_threshold: Amount;
|
||||
|
||||
contact_data?: ChallengeContactData;
|
||||
|
||||
// 'payto' address pointing the bank account
|
||||
// where to send cashouts. This field is optional
|
||||
// because not all the accounts are required to participate
|
||||
// in the merchants' circuit. One example is the exchange:
|
||||
// that never cashouts. Registering these accounts can
|
||||
// be done via the access API.
|
||||
cashout_payto_uri?: string;
|
||||
}
|
||||
|
||||
|
||||
export interface CashoutRequest {
|
||||
|
||||
// Optional subject to associate to the
|
||||
// cashout operation. This data will appear
|
||||
// as the incoming wire transfer subject in
|
||||
// the user's external bank account.
|
||||
subject?: string;
|
||||
|
||||
// That is the plain amount that the user specified
|
||||
// to cashout. Its $currency is the (regional) currency of the
|
||||
// bank instance.
|
||||
amount_debit: Amount;
|
||||
|
||||
// That is the amount that will effectively be
|
||||
// transferred by the bank to the user's bank
|
||||
// account, that is external to the regional currency.
|
||||
// It is expressed in the fiat currency and
|
||||
// is calculated after the cashout fee and the
|
||||
// exchange rate. See the /cashout-rates call.
|
||||
// The client needs to calculate this amount
|
||||
// correctly based on the amount_debit and the cashout rate,
|
||||
// otherwise the request will fail.
|
||||
amount_credit: Amount;
|
||||
|
||||
// Which channel the TAN should be sent to. If
|
||||
// this field is missing, it defaults to SMS.
|
||||
// The default choice prefers to change the communication
|
||||
// channel respect to the one used to issue this request.
|
||||
tan_channel?: TanChannel;
|
||||
}
|
||||
|
||||
export interface CashoutPending {
|
||||
// ID identifying the operation being created
|
||||
// and now waiting for the TAN confirmation.
|
||||
cashout_id: string;
|
||||
}
|
||||
|
||||
export interface CashoutConfirmRequest {
|
||||
// the TAN that confirms $CASHOUT_ID.
|
||||
tan: string;
|
||||
}
|
||||
|
||||
export interface CashoutConversionResponse {
|
||||
// Amount that the user will get deducted from their regional
|
||||
// bank account, according to the 'amount_credit' value.
|
||||
amount_debit: Amount;
|
||||
// Amount that the user will receive in their fiat
|
||||
// bank account, according to 'amount_debit'.
|
||||
amount_credit: Amount;
|
||||
}
|
||||
|
||||
export interface Cashouts {
|
||||
// Every string represents a cash-out operation ID.
|
||||
cashouts: CashoutInfo[];
|
||||
}
|
||||
|
||||
export interface CashoutInfo {
|
||||
cashout_id: string;
|
||||
status: "pending" | "confirmed";
|
||||
}
|
||||
export interface GlobalCashouts {
|
||||
// Every string represents a cash-out operation ID.
|
||||
cashouts: GlobalCashoutInfo[];
|
||||
}
|
||||
export interface GlobalCashoutInfo {
|
||||
cashout_id: string;
|
||||
username: string;
|
||||
status: "pending" | "confirmed";
|
||||
}
|
||||
|
||||
export interface CashoutStatusResponse {
|
||||
status: "pending" | "confirmed";
|
||||
|
||||
// Amount debited to the internal
|
||||
// regional currency bank account.
|
||||
amount_debit: Amount;
|
||||
|
||||
// Amount credited to the external bank account.
|
||||
amount_credit: Amount;
|
||||
|
||||
// Transaction subject.
|
||||
subject: string;
|
||||
|
||||
// Fiat bank account that will receive the cashed out amount.
|
||||
// Specified as a payto URI.
|
||||
credit_payto_uri: string;
|
||||
|
||||
// Time when the cashout was created.
|
||||
creation_time: Timestamp;
|
||||
|
||||
// Time when the cashout was confirmed via its TAN.
|
||||
// Missing when the operation wasn't confirmed yet.
|
||||
confirmation_time?: Timestamp;
|
||||
}
|
||||
|
||||
export interface ConversionRatesResponse {
|
||||
|
||||
// Exchange rate to buy the local currency from the external one
|
||||
buy_at_ratio: DecimalNumber;
|
||||
|
||||
// Exchange rate to sell the local currency for the external one
|
||||
sell_at_ratio: DecimalNumber;
|
||||
|
||||
// Fee to subtract after applying the buy ratio.
|
||||
buy_in_fee: DecimalNumber;
|
||||
|
||||
// Fee to subtract after applying the sell ratio.
|
||||
sell_out_fee: DecimalNumber;
|
||||
}
|
||||
|
||||
export enum MonitorTimeframeParam{
|
||||
hour, day, month, year, decade,
|
||||
}
|
||||
|
||||
export interface MonitorResponse {
|
||||
|
||||
// This number identifies how many cashin operations
|
||||
// took place in the timeframe specified in the request.
|
||||
// This number corresponds to how many withdrawals have
|
||||
// been initiated by a wallet owner. Note: wallet owners
|
||||
// are NOT required to be customers of the libeufin-bank.
|
||||
cashinCount: number;
|
||||
|
||||
// This amount accounts how much external currency has been
|
||||
// spent to withdraw Taler coins in the internal currency.
|
||||
// The exact amount of internal currency being created can be
|
||||
// calculated using the advertised conversion rates.
|
||||
cashinExternalVolume: Amount;
|
||||
|
||||
// This number identifies how many cashout operations were
|
||||
// confirmed in the timeframe speficied in the request.
|
||||
cashoutCount: number;
|
||||
|
||||
// This amount corresponds to how much *external* currency was
|
||||
// paid by the libeufin-bank administrator to fulfill all the
|
||||
// confirmed cashouts related to the timeframe specified in the
|
||||
// request.
|
||||
cashoutExternalVolume: Amount;
|
||||
|
||||
// This number identifies how many payments were made by a
|
||||
// Taler exchange to a merchant bank account in the internal
|
||||
// currency, in the timeframe specified in the request.
|
||||
talerPayoutCount: number;
|
||||
|
||||
// This amount accounts the overall *internal* currency that
|
||||
// has been paid by a Taler exchange to a merchant internal
|
||||
// bank account, in the timeframe specified in the request.
|
||||
talerPayoutInternalVolume: Amount;
|
||||
}
|
||||
|
||||
|
||||
}
|
62
packages/taler-util/src/http-client/utils.ts
Normal file
62
packages/taler-util/src/http-client/utils.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { base64FromArrayBuffer } from "../base64.js";
|
||||
import { stringToBytes } from "../taler-crypto.js";
|
||||
import { AccessToken, TalerAuthentication } from "./types.js";
|
||||
|
||||
/**
|
||||
* Helper function to generate the "Authorization" HTTP header.
|
||||
*/
|
||||
export function makeBasicAuthHeader(username: string, password: string): string {
|
||||
const auth = `${username}:${password}`;
|
||||
const authEncoded: string = base64FromArrayBuffer(stringToBytes(auth));
|
||||
return `Basic ${authEncoded}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* rfc8959
|
||||
* @param token
|
||||
* @returns
|
||||
*/
|
||||
export function makeBearerTokenAuthHeader(token: AccessToken): string {
|
||||
return `Bearer secret-token:${token}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* https://bugs.gnunet.org/view.php?id=7949
|
||||
*/
|
||||
export function addPaginationParams(url: URL, pagination?: PaginationParams) {
|
||||
if (!pagination) return;
|
||||
if (pagination.timoutMs) {
|
||||
url.searchParams.set("long_poll_ms", String(pagination.timoutMs))
|
||||
}
|
||||
if (pagination.offset) {
|
||||
url.searchParams.set("start", pagination.offset)
|
||||
}
|
||||
if (pagination.limit) {
|
||||
url.searchParams.set("delta", String(pagination.limit))
|
||||
}
|
||||
}
|
||||
|
||||
export type UserAndPassword = {
|
||||
username: string,
|
||||
password: string,
|
||||
}
|
||||
|
||||
export type UserAndToken = {
|
||||
username: string,
|
||||
token: AccessToken,
|
||||
}
|
||||
|
||||
export type PaginationParams = {
|
||||
/**
|
||||
* row identifier as the starting point of the query
|
||||
*/
|
||||
offset?: string,
|
||||
/**
|
||||
* max number of element in the result response
|
||||
*/
|
||||
limit?: number,
|
||||
/**
|
||||
* milliseconds the server should wait for at least one result to be shown
|
||||
*/
|
||||
timoutMs?: number,
|
||||
}
|
@ -50,7 +50,7 @@ export interface HttpResponse {
|
||||
export const DEFAULT_REQUEST_TIMEOUT_MS = 60000;
|
||||
|
||||
export interface HttpRequestOptions {
|
||||
method?: "POST" | "PUT" | "GET" | "DELETE";
|
||||
method?: "POST" | "PATCH" | "PUT" | "GET" | "DELETE";
|
||||
headers?: { [name: string]: string };
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user