aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-util
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-10-30 15:27:25 -0300
committerSebastian <sebasjm@gmail.com>2023-10-30 15:27:25 -0300
commit768838285c25cbb1b171f645e8efb37a3c14273a (patch)
tree3404a7ea452a357baf4ebfc6c3b400f601849744 /packages/taler-util
parentb7ba3119c1ff0d9ae3432cf0de1ef8cf92fc193c (diff)
local error impl: errors shown fixed position that are wiped when moved from the view
Diffstat (limited to 'packages/taler-util')
-rw-r--r--packages/taler-util/src/amounts.ts21
-rw-r--r--packages/taler-util/src/http-client/types.ts87
-rw-r--r--packages/taler-util/src/index.node.ts1
-rw-r--r--packages/taler-util/src/payto.ts26
-rw-r--r--packages/taler-util/src/taleruri.ts22
5 files changed, 111 insertions, 46 deletions
diff --git a/packages/taler-util/src/amounts.ts b/packages/taler-util/src/amounts.ts
index 082a8168e..5c6444b00 100644
--- a/packages/taler-util/src/amounts.ts
+++ b/packages/taler-util/src/amounts.ts
@@ -26,6 +26,9 @@ import {
codecForString,
codecForNumber,
Codec,
+ Context,
+ DecodingError,
+ renderContext,
} from "./codec.js";
import { AmountString } from "./taler-types.js";
@@ -74,7 +77,23 @@ export const codecForAmountJson = (): Codec<AmountJson> =>
.property("fraction", codecForNumber())
.build("AmountJson");
-export const codecForAmountString = (): Codec<AmountString> => codecForString() as Codec<AmountString>;
+export function codecForAmountString(): Codec<AmountString> {
+ return {
+ decode(x: any, c?: Context): AmountString {
+ if (typeof x !== "string") {
+ throw new DecodingError(
+ `expected string at ${renderContext(c)} but got ${typeof x}`,
+ );
+ }
+ if (Amounts.parse(x) === undefined) {
+ throw new DecodingError(
+ `invalid amount at ${renderContext(c)} got "${x}"`,
+ );
+ }
+ return x as AmountString;
+ },
+ };
+}
/**
* Result of a possibly overflowing operation.
diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts
index b9a5032d1..1bb8f99c1 100644
--- a/packages/taler-util/src/http-client/types.ts
+++ b/packages/taler-util/src/http-client/types.ts
@@ -1,6 +1,8 @@
import { codecForAmountString } from "../amounts.js";
import { Codec, buildCodecForObject, buildCodecForUnion, codecForBoolean, codecForConstString, codecForEither, codecForList, codecForMap, codecForNumber, codecForString, codecOptional } from "../codec.js";
+import { PaytoString, PaytoUri, codecForPaytoString } from "../payto.js";
import { AmountString } from "../taler-types.js";
+import { TalerActionString, WithdrawUriResult, codecForTalerActionString } from "../taleruri.js";
import { codecForTimestamp } from "../time.js";
import { TalerErrorDetail } from "../wallet-types.js";
@@ -255,7 +257,7 @@ const codecForPublicAccount = (): Codec<TalerCorebankApi.PublicAccount> =>
buildCodecForObject<TalerCorebankApi.PublicAccount>()
.property("account_name", codecForString())
.property("balance", codecForBalance())
- .property("payto_uri", codecForPaytoURI())
+ .property("payto_uri", codecForPaytoString())
.build("TalerCorebankApi.PublicAccount")
export const codecForPublicAccountsResponse =
@@ -285,10 +287,10 @@ export const codecForAccountData =
buildCodecForObject<TalerCorebankApi.AccountData>()
.property("name", codecForString())
.property("balance", codecForBalance())
- .property("payto_uri", codecForPaytoURI())
+ .property("payto_uri", codecForPaytoString())
.property("debit_threshold", codecForAmountString())
.property("contact_data", codecOptional(codecForChallengeContactData()))
- .property("cashout_payto_uri", codecOptional(codecForPaytoURI()))
+ .property("cashout_payto_uri", codecOptional(codecForPaytoString()))
.build("TalerCorebankApi.AccountData")
@@ -309,9 +311,9 @@ export const codecForBankAccountTransactionInfo =
(): Codec<TalerCorebankApi.BankAccountTransactionInfo> =>
buildCodecForObject<TalerCorebankApi.BankAccountTransactionInfo>()
.property("amount", codecForAmountString())
- .property("creditor_payto_uri", codecForPaytoURI())
+ .property("creditor_payto_uri", codecForPaytoString())
.property("date", codecForTimestamp)
- .property("debtor_payto_uri", codecForPaytoURI())
+ .property("debtor_payto_uri", codecForPaytoString())
.property("direction", codecForEither(codecForConstString("debit"), codecForConstString("credit")))
.property("row_id", codecForNumber())
.property("subject", codecForString())
@@ -320,7 +322,7 @@ export const codecForBankAccountTransactionInfo =
export const codecForBankAccountCreateWithdrawalResponse =
(): Codec<TalerCorebankApi.BankAccountCreateWithdrawalResponse> =>
buildCodecForObject<TalerCorebankApi.BankAccountCreateWithdrawalResponse>()
- .property("taler_withdraw_uri", codecForTalerWithdrawalURI())
+ .property("taler_withdraw_uri", codecForTalerActionString())
.property("withdrawal_id", codecForString())
.build("TalerCorebankApi.BankAccountCreateWithdrawalResponse");
@@ -330,7 +332,7 @@ export const codecForBankAccountGetWithdrawalResponse =
.property("aborted", codecForBoolean())
.property("amount", codecForAmountString())
.property("confirmation_done", codecForBoolean())
- .property("selected_exchange_account", codecOptional(codecForString()))
+ .property("selected_exchange_account", codecOptional(codecForPaytoString()))
.property("selected_reserve_pub", codecOptional(codecForString()))
.property("selection_done", (codecForBoolean()))
.build("TalerCorebankApi.BankAccountGetWithdrawalResponse");
@@ -382,7 +384,7 @@ export const codecForCashoutStatusResponse =
.property("amount_debit", codecForAmountString())
.property("confirmation_time", codecForTimestamp)
.property("creation_time", codecForTimestamp)
- .property("credit_payto_uri", codecForPaytoURI())
+ .property("credit_payto_uri", codecForPaytoString())
.property("status", codecForEither(codecForConstString("pending"), codecForConstString("confirmed")))
.property("subject", codecForString())
.build("TalerCorebankApi.CashoutStatusResponse");
@@ -423,7 +425,7 @@ export const codecForBankWithdrawalOperationStatus =
.property("amount", codecForAmountString())
.property("confirm_transfer_url", codecOptional(codecForURL()))
.property("selection_done", codecForBoolean())
- .property("sender_wire", codecForPaytoURI())
+ .property("sender_wire", codecForPaytoString())
.property("suggested_exchange", codecOptional(codecForString()))
.property("transfer_done", codecForBoolean())
.property("wire_types", codecForList(codecForString()))
@@ -439,7 +441,7 @@ export const codecForBankWithdrawalOperationPostResponse =
export const codecForMerchantIncomingHistory =
(): Codec<TalerRevenueApi.MerchantIncomingHistory> =>
buildCodecForObject<TalerRevenueApi.MerchantIncomingHistory>()
- .property("credit_account", codecForPaytoURI())
+ .property("credit_account", codecForPaytoString())
.property("incoming_transactions", codecForList(codecForMerchantIncomingBankTransaction()))
.build("TalerRevenueApi.MerchantIncomingHistory");
@@ -448,7 +450,7 @@ export const codecForMerchantIncomingBankTransaction =
buildCodecForObject<TalerRevenueApi.MerchantIncomingBankTransaction>()
.property("amount", codecForAmountString())
.property("date", codecForTimestamp)
- .property("debit_account", codecForPaytoURI())
+ .property("debit_account", codecForPaytoString())
.property("exchange_url", codecForURL())
.property("row_id", codecForNumber())
.property("wtid", codecForString())
@@ -464,7 +466,7 @@ export const codecForTransferResponse =
export const codecForIncomingHistory =
(): Codec<TalerWireGatewayApi.IncomingHistory> =>
buildCodecForObject<TalerWireGatewayApi.IncomingHistory>()
- .property("credit_account", codecForString())
+ .property("credit_account", codecForPaytoString())
.property("incoming_transactions", codecForList(codecForIncomingBankTransaction()))
.build("TalerWireGatewayApi.IncomingHistory");
@@ -479,7 +481,7 @@ export const codecForIncomingReserveTransaction =
buildCodecForObject<TalerWireGatewayApi.IncomingReserveTransaction>()
.property("amount", codecForAmountString())
.property("date", codecForTimestamp)
- .property("debit_account", codecForPaytoURI())
+ .property("debit_account", codecForPaytoString())
.property("reserve_pub", codecForString())
.property("row_id", codecForNumber())
.property("type", codecForConstString("RESERVE"))
@@ -489,9 +491,9 @@ export const codecForIncomingWadTransaction =
(): Codec<TalerWireGatewayApi.IncomingWadTransaction> =>
buildCodecForObject<TalerWireGatewayApi.IncomingWadTransaction>()
.property("amount", codecForAmountString())
- .property("credit_account", codecForPaytoURI())
+ .property("credit_account", codecForPaytoString())
.property("date", codecForTimestamp)
- .property("debit_account", codecForPaytoURI())
+ .property("debit_account", codecForPaytoString())
.property("origin_exchange_url", codecForURL())
.property("row_id", codecForNumber())
.property("type", codecForConstString("WAD"))
@@ -501,7 +503,7 @@ export const codecForIncomingWadTransaction =
export const codecForOutgoingHistory =
(): Codec<TalerWireGatewayApi.OutgoingHistory> =>
buildCodecForObject<TalerWireGatewayApi.OutgoingHistory>()
- .property("debit_account", codecForString())
+ .property("debit_account", codecForPaytoString())
.property("outgoing_transactions", codecForList(codecForOutgoingBankTransaction()))
.build("TalerWireGatewayApi.OutgoingHistory");
@@ -509,7 +511,7 @@ export const codecForOutgoingBankTransaction =
(): Codec<TalerWireGatewayApi.OutgoingBankTransaction> =>
buildCodecForObject<TalerWireGatewayApi.OutgoingBankTransaction>()
.property("amount", codecForAmountString())
- .property("credit_account", codecForPaytoURI())
+ .property("credit_account", codecForPaytoString())
.property("date", codecForTimestamp)
.property("exchange_base_url", codecForURL())
.property("row_id", codecForNumber())
@@ -537,7 +539,6 @@ type DecimalNumber = number;
const codecForURL = codecForString
const codecForLibtoolVersion = codecForString
const codecForCurrencyName = codecForString
-const codecForPaytoURI = codecForString
const codecForTalerWithdrawalURI = codecForString
const codecForDecimalNumber = codecForNumber
@@ -583,7 +584,7 @@ export namespace TalerWireGatewayApi {
wtid: ShortHashCode;
// The recipient's account identifier as a payto URI.
- credit_account: string;
+ credit_account: PaytoString;
}
export interface IncomingHistory {
@@ -595,7 +596,7 @@ export namespace TalerWireGatewayApi {
// 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;
+ credit_account: PaytoString;
}
@@ -617,7 +618,7 @@ export namespace TalerWireGatewayApi {
amount: AmountString;
// Payto URI to identify the sender of funds.
- debit_account: string;
+ debit_account: PaytoString;
// The reserve public key extracted from the transaction details.
reserve_pub: EddsaPublicKey;
@@ -638,10 +639,10 @@ export namespace TalerWireGatewayApi {
// Payto URI to identify the receiver of funds.
// This must be one of the exchange's bank accounts.
- credit_account: string;
+ credit_account: PaytoString;
// Payto URI to identify the sender of funds.
- debit_account: string;
+ debit_account: PaytoString;
// Base URL of the exchange that originated the wad.
origin_exchange_url: string;
@@ -660,7 +661,7 @@ export namespace TalerWireGatewayApi {
// 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;
+ debit_account: PaytoString;
}
@@ -676,7 +677,7 @@ export namespace TalerWireGatewayApi {
amount: AmountString;
// Payto URI to identify the receiver of funds.
- credit_account: string;
+ credit_account: PaytoString;
// The wire transfer ID in the outgoing transaction.
wtid: ShortHashCode;
@@ -697,7 +698,7 @@ export namespace TalerWireGatewayApi {
// 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;
+ debit_account: PaytoString;
}
export interface AddIncomingResponse {
@@ -729,7 +730,7 @@ export namespace TalerRevenueApi {
// 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;
+ credit_account: PaytoString;
}
@@ -745,7 +746,7 @@ export namespace TalerRevenueApi {
amount: AmountString;
// Payto URI to identify the sender of funds.
- debit_account: string;
+ debit_account: PaytoString;
// Base URL of the exchange where the transfer originated form.
exchange_url: string;
@@ -791,7 +792,7 @@ export namespace TalerBankIntegrationApi {
// Bank account of the customer that is withdrawing, as a
// payto URI.
- sender_wire?: string;
+ sender_wire?: PaytoString;
// Suggestion for an exchange given by the bank.
suggested_exchange?: string;
@@ -811,7 +812,7 @@ export namespace TalerBankIntegrationApi {
reserve_pub: string;
// Payto address of the exchange selected for the withdrawal.
- selected_exchange: string;
+ selected_exchange: PaytoString;
}
export interface BankWithdrawalOperationPostResponse {
@@ -867,7 +868,7 @@ export namespace TalerCorebankApi {
withdrawal_id: string;
// URI that can be passed to the wallet to initiate the withdrawal.
- taler_withdraw_uri: string;
+ taler_withdraw_uri: TalerActionString;
}
export interface BankAccountGetWithdrawalResponse {
// Amount that will be withdrawn with this withdrawal operation.
@@ -891,7 +892,7 @@ export namespace TalerCorebankApi {
// 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;
+ selected_exchange_account: PaytoString | undefined;
}
export interface BankAccountTransactionsResponse {
@@ -899,8 +900,8 @@ export namespace TalerCorebankApi {
}
export interface BankAccountTransactionInfo {
- creditor_payto_uri: string;
- debtor_payto_uri: string;
+ creditor_payto_uri: PaytoString;
+ debtor_payto_uri: PaytoString;
amount: AmountString;
direction: "debit" | "credit";
@@ -916,13 +917,13 @@ export namespace TalerCorebankApi {
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;
+ payto_uri: PaytoString;
// 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;
+ amount?: AmountString;
}
export interface RegisterAccountRequest {
@@ -958,11 +959,11 @@ export namespace TalerCorebankApi {
// 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;
+ cashout_payto_uri?: PaytoString;
// Internal payto URI of this bank account.
// Used mostly for testing.
- internal_payto_uri?: string;
+ internal_payto_uri?: PaytoString;
}
export interface ChallengeContactData {
@@ -987,7 +988,7 @@ export namespace TalerCorebankApi {
// 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;
+ cashout_address?: PaytoString;
// Legal name associated with $username.
// When missing, the old name is kept.
@@ -1011,7 +1012,7 @@ export namespace TalerCorebankApi {
public_accounts: PublicAccount[];
}
export interface PublicAccount {
- payto_uri: string;
+ payto_uri: PaytoString;
balance: Balance;
@@ -1049,7 +1050,7 @@ export namespace TalerCorebankApi {
balance: Balance;
// payto://-URI of the account.
- payto_uri: string;
+ payto_uri: PaytoString;
// Number indicating the max debit allowed for the requesting user.
debit_threshold: AmountString;
@@ -1062,7 +1063,7 @@ export namespace TalerCorebankApi {
// 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;
+ cashout_payto_uri?: PaytoString;
}
@@ -1151,7 +1152,7 @@ export namespace TalerCorebankApi {
// Fiat bank account that will receive the cashed out amount.
// Specified as a payto URI.
- credit_payto_uri: string;
+ credit_payto_uri: PaytoString;
// Time when the cashout was created.
creation_time: Timestamp;
diff --git a/packages/taler-util/src/index.node.ts b/packages/taler-util/src/index.node.ts
index 018b4767f..619da0127 100644
--- a/packages/taler-util/src/index.node.ts
+++ b/packages/taler-util/src/index.node.ts
@@ -21,3 +21,4 @@ initNodePrng();
export * from "./index.js";
export * from "./talerconfig.js";
export * from "./globbing/minimatch.js";
+export { setPrintHttpRequestAsCurl } from "./http-impl.node.js"; \ No newline at end of file
diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts
index 85870afcd..3df174944 100644
--- a/packages/taler-util/src/payto.ts
+++ b/packages/taler-util/src/payto.ts
@@ -15,6 +15,7 @@
*/
import { generateFakeSegwitAddress } from "./bitcoin.js";
+import { Codec, Context, DecodingError, renderContext } from "./codec.js";
import { URLSearchParams } from "./url.js";
export type PaytoUri =
@@ -23,6 +24,27 @@ export type PaytoUri =
| PaytoUriTalerBank
| PaytoUriBitcoin;
+declare const __payto_str: unique symbol;
+export type PaytoString = string & { [__payto_str]: true };
+
+export function codecForPaytoString(): Codec<PaytoString> {
+ return {
+ decode(x: any, c?: Context): PaytoString {
+ if (typeof x !== "string") {
+ throw new DecodingError(
+ `expected string at ${renderContext(c)} but got ${typeof x}`,
+ );
+ }
+ if (!x.startsWith(paytoPfx)) {
+ throw new DecodingError(
+ `expected start with payto at ${renderContext(c)} but got "${x}"`,
+ );
+ }
+ return x as PaytoString;
+ },
+ };
+}
+
export interface PaytoUriGeneric {
targetType: PaytoType | string;
targetPath: string;
@@ -143,13 +165,13 @@ export function addPaytoQueryParams(
* @param p
* @returns
*/
-export function stringifyPaytoUri(p: PaytoUri): string {
+export function stringifyPaytoUri(p: PaytoUri): PaytoString {
const url = new URL(`${paytoPfx}${p.targetType}/${p.targetPath}`);
const paramList = !p.params ? [] : Object.entries(p.params);
paramList.forEach(([key, value]) => {
url.searchParams.set(key, value);
});
- return url.href;
+ return url.href as PaytoString;
}
/**
diff --git a/packages/taler-util/src/taleruri.ts b/packages/taler-util/src/taleruri.ts
index 9568636b8..cf5d3f413 100644
--- a/packages/taler-util/src/taleruri.ts
+++ b/packages/taler-util/src/taleruri.ts
@@ -14,6 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
+import { Codec, Context, DecodingError, renderContext } from "./codec.js";
import { canonicalizeBaseUrl } from "./helpers.js";
import { AmountString } from "./taler-types.js";
import { URLSearchParams, URL } from "./url.js";
@@ -32,6 +33,27 @@ export type TalerUri =
| WithdrawExchangeUri
| AuditorUri;
+declare const __action_str: unique symbol;
+export type TalerActionString = string & { [__action_str]: true };
+
+export function codecForTalerActionString(): Codec<TalerActionString> {
+ return {
+ decode(x: any, c?: Context): TalerActionString {
+ if (typeof x !== "string") {
+ throw new DecodingError(
+ `expected string at ${renderContext(c)} but got ${typeof x}`,
+ );
+ }
+ if (parseTalerUri(x) === undefined) {
+ throw new DecodingError(
+ `invalid taler action at ${renderContext(c)} but got "${x}"`,
+ );
+ }
+ return x as TalerActionString;
+ },
+ };
+}
+
export interface PayUriResult {
type: TalerUriAction.Pay;
merchantBaseUrl: string;