From 2005273d1286819e68d3ea7a3290f8c357be5e40 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sun, 22 Oct 2023 13:50:34 -0300 Subject: add codecAmountString for string field that are just amount, note that this does not add the validation so is just type checking for future validation --- packages/taler-util/src/ReserveStatus.ts | 11 ++---- packages/taler-util/src/ReserveTransaction.ts | 13 ++++---- packages/taler-util/src/amounts.ts | 4 +-- packages/taler-util/src/http-client/types.ts | 48 +++++++++++++-------------- packages/taler-util/src/merchant-api-types.ts | 2 +- packages/taler-util/src/taler-types.ts | 20 ++++++----- packages/taler-util/src/taleruri.test.ts | 3 +- packages/taler-util/src/taleruri.ts | 2 +- packages/taler-util/src/wallet-types.ts | 16 ++++----- 9 files changed, 58 insertions(+), 61 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/ReserveStatus.ts b/packages/taler-util/src/ReserveStatus.ts index be9fa9e8e..a6d0dc108 100644 --- a/packages/taler-util/src/ReserveStatus.ts +++ b/packages/taler-util/src/ReserveStatus.ts @@ -21,17 +21,12 @@ /** * Imports. */ +import { codecForAmountString } from "./amounts.js"; import { - codecForString, - buildCodecForObject, - codecForList, Codec, + buildCodecForObject } from "./codec.js"; import { AmountString } from "./taler-types.js"; -import { - ReserveTransaction, - codecForReserveTransaction, -} from "./ReserveTransaction.js"; /** * Status of a reserve. @@ -47,5 +42,5 @@ export interface ReserveStatus { export const codecForReserveStatus = (): Codec => buildCodecForObject() - .property("balance", codecForString()) + .property("balance", codecForAmountString()) .build("ReserveStatus"); diff --git a/packages/taler-util/src/ReserveTransaction.ts b/packages/taler-util/src/ReserveTransaction.ts index 5d3f86b1a..7a3c69d07 100644 --- a/packages/taler-util/src/ReserveTransaction.ts +++ b/packages/taler-util/src/ReserveTransaction.ts @@ -23,6 +23,7 @@ /** * Imports. */ +import { codecForAmountString } from "./amounts.js"; import { codecForString, buildCodecForObject, @@ -189,18 +190,18 @@ export type ReserveTransaction = export const codecForReserveWithdrawTransaction = (): Codec => buildCodecForObject() - .property("amount", codecForString()) + .property("amount", codecForAmountString()) .property("h_coin_envelope", codecForString()) .property("h_denom_pub", codecForString()) .property("reserve_sig", codecForString()) .property("type", codecForConstString(ReserveTransactionType.Withdraw)) - .property("withdraw_fee", codecForString()) + .property("withdraw_fee", codecForAmountString()) .build("ReserveWithdrawTransaction"); export const codecForReserveCreditTransaction = (): Codec => buildCodecForObject() - .property("amount", codecForString()) + .property("amount", codecForAmountString()) .property("sender_account_url", codecForString()) .property("timestamp", codecForTimestamp) .property("wire_reference", codecForNumber()) @@ -210,8 +211,8 @@ export const codecForReserveCreditTransaction = export const codecForReserveClosingTransaction = (): Codec => buildCodecForObject() - .property("amount", codecForString()) - .property("closing_fee", codecForString()) + .property("amount", codecForAmountString()) + .property("closing_fee", codecForAmountString()) .property("exchange_pub", codecForString()) .property("exchange_sig", codecForString()) .property("h_wire", codecForString()) @@ -223,7 +224,7 @@ export const codecForReserveClosingTransaction = export const codecForReserveRecoupTransaction = (): Codec => buildCodecForObject() - .property("amount", codecForString()) + .property("amount", codecForAmountString()) .property("coin_pub", codecForString()) .property("exchange_pub", codecForString()) .property("exchange_sig", codecForString()) diff --git a/packages/taler-util/src/amounts.ts b/packages/taler-util/src/amounts.ts index 04343b8e9..ee35a6bbe 100644 --- a/packages/taler-util/src/amounts.ts +++ b/packages/taler-util/src/amounts.ts @@ -74,7 +74,7 @@ export const codecForAmountJson = (): Codec => .property("fraction", codecForNumber()) .build("AmountJson"); -export const codecForAmountString = (): Codec => codecForString(); +export const codecForAmountString = (): Codec => codecForAmountString(); /** * Result of a possibly overflowing operation. @@ -93,7 +93,7 @@ export interface Result { /** * Type for things that are treated like amounts. */ -export type AmountLike = AmountString | AmountJson; +export type AmountLike = string | AmountString | AmountJson; export interface DivmodResult { quotient: number; diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts index b0d6c163b..be6e72a2e 100644 --- a/packages/taler-util/src/http-client/types.ts +++ b/packages/taler-util/src/http-client/types.ts @@ -1,5 +1,6 @@ import { codecForAmountString } from "../amounts.js"; import { Codec, buildCodecForObject, buildCodecForUnion, codecForBoolean, codecForConstString, codecForEither, codecForList, codecForMap, codecForNumber, codecForString, codecOptional } from "../codec.js"; +import { AmountString } from "../taler-types.js"; import { codecForTimestamp } from "../time.js"; import { TalerErrorDetail } from "../wallet-types.js"; @@ -148,9 +149,6 @@ type SafeUint64 = number; type ImageDataUrl = string; -// :. -type Amount = string; - type WadId = string; interface Timestamp { @@ -593,7 +591,7 @@ export namespace TalerWireGatewayApi { request_uid: HashCode; // Amount to transfer. - amount: Amount; + amount: AmountString; // Base URL of the exchange. Shall be included by the bank gateway // in the appropriate section of the wire transfer details. @@ -636,7 +634,7 @@ export namespace TalerWireGatewayApi { date: Timestamp; // Amount transferred. - amount: Amount; + amount: AmountString; // Payto URI to identify the sender of funds. debit_account: string; @@ -656,7 +654,7 @@ export namespace TalerWireGatewayApi { date: Timestamp; // Amount transferred. - amount: Amount; + amount: AmountString; // Payto URI to identify the receiver of funds. // This must be one of the exchange's bank accounts. @@ -695,7 +693,7 @@ export namespace TalerWireGatewayApi { date: Timestamp; // Amount transferred. - amount: Amount; + amount: AmountString; // Payto URI to identify the receiver of funds. credit_account: string; @@ -709,7 +707,7 @@ export namespace TalerWireGatewayApi { export interface AddIncomingRequest { // Amount to transfer. - amount: Amount; + amount: AmountString; // Reserve public key that is included in the wire transfer details // to identify the reserve that is being topped up. @@ -764,7 +762,7 @@ export namespace TalerRevenueApi { date: Timestamp; // Amount transferred. - amount: Amount; + amount: AmountString; // Payto URI to identify the sender of funds. debit_account: string; @@ -809,7 +807,7 @@ export namespace TalerBankIntegrationApi { // Amount that will be withdrawn with this operation // (raw amount without fee considerations). - amount: Amount; + amount: AmountString; // Bank account of the customer that is withdrawing, as a // payto URI. @@ -877,7 +875,7 @@ export namespace TalerCorebankApi { export interface BankAccountCreateWithdrawalRequest { // Amount to withdraw. - amount: Amount; + amount: AmountString; } export interface BankAccountCreateWithdrawalResponse { // ID of the withdrawal, can be used to view/modify the withdrawal operation. @@ -888,7 +886,7 @@ export namespace TalerCorebankApi { } export interface BankAccountGetWithdrawalResponse { // Amount that will be withdrawn with this withdrawal operation. - amount: Amount; + amount: AmountString; // Was the withdrawal aborted? aborted: boolean; @@ -919,7 +917,7 @@ export namespace TalerCorebankApi { creditor_payto_uri: string; debtor_payto_uri: string; - amount: Amount; + amount: AmountString; direction: "debit" | "credit"; subject: string; @@ -1042,7 +1040,7 @@ export namespace TalerCorebankApi { accounts: AccountMinimalData[]; } export interface Balance { - amount: Amount; + amount: AmountString; credit_debit_indicator: "credit" | "debit"; } export interface AccountMinimalData { @@ -1056,7 +1054,7 @@ export namespace TalerCorebankApi { balance: Balance; // Number indicating the max debit allowed for the requesting user. - debit_threshold: Amount; + debit_threshold: AmountString; } export interface AccountData { @@ -1070,7 +1068,7 @@ export namespace TalerCorebankApi { payto_uri: string; // Number indicating the max debit allowed for the requesting user. - debit_threshold: Amount; + debit_threshold: AmountString; contact_data?: ChallengeContactData; @@ -1095,7 +1093,7 @@ export namespace TalerCorebankApi { // That is the plain amount that the user specified // to cashout. Its $currency is the (regional) currency of the // bank instance. - amount_debit: Amount; + amount_debit: AmountString; // That is the amount that will effectively be // transferred by the bank to the user's bank @@ -1106,7 +1104,7 @@ export namespace TalerCorebankApi { // 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; + amount_credit: AmountString; // Which channel the TAN should be sent to. If // this field is missing, it defaults to SMS. @@ -1129,10 +1127,10 @@ export namespace TalerCorebankApi { 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_debit: AmountString; // Amount that the user will receive in their fiat // bank account, according to 'amount_debit'. - amount_credit: Amount; + amount_credit: AmountString; } export interface Cashouts { @@ -1159,10 +1157,10 @@ export namespace TalerCorebankApi { // Amount debited to the internal // regional currency bank account. - amount_debit: Amount; + amount_debit: AmountString; // Amount credited to the external bank account. - amount_credit: Amount; + amount_credit: AmountString; // Transaction subject. subject: string; @@ -1211,7 +1209,7 @@ export namespace TalerCorebankApi { // 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; + cashinExternalVolume: AmountString; // This number identifies how many cashout operations were // confirmed in the timeframe speficied in the request. @@ -1221,7 +1219,7 @@ export namespace TalerCorebankApi { // paid by the libeufin-bank administrator to fulfill all the // confirmed cashouts related to the timeframe specified in the // request. - cashoutExternalVolume: Amount; + cashoutExternalVolume: AmountString; // This number identifies how many payments were made by a // Taler exchange to a merchant bank account in the internal @@ -1231,7 +1229,7 @@ export namespace TalerCorebankApi { // 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; + talerPayoutInternalVolume: AmountString; } diff --git a/packages/taler-util/src/merchant-api-types.ts b/packages/taler-util/src/merchant-api-types.ts index 9933b93dc..9a7740088 100644 --- a/packages/taler-util/src/merchant-api-types.ts +++ b/packages/taler-util/src/merchant-api-types.ts @@ -90,7 +90,7 @@ export const codecForMerchantRefundDetails = (): Codec => buildCodecForObject() .property("reason", codecForString()) .property("pending", codecForBoolean()) - .property("amount", codecForString()) + .property("amount", codecForAmountString()) .property("timestamp", codecForTimestamp) .build("PostOrderResponse"); diff --git a/packages/taler-util/src/taler-types.ts b/packages/taler-util/src/taler-types.ts index 4b3a426f5..87925a3a4 100644 --- a/packages/taler-util/src/taler-types.ts +++ b/packages/taler-util/src/taler-types.ts @@ -1310,7 +1310,9 @@ export const codecForDenominationPubKey = () => .alternative(DenomKeyType.ClauseSchnorr, codecForCsDenominationPubKey()) .build("DenominationPubKey"); -export type AmountString = string; +declare const __amount_str: unique symbol; +export type AmountString = string & { [__amount_str]: true }; +// export type AmountString = string; export type Base32String = string; export type EddsaSignatureString = string; export type EddsaPublicKeyString = string; @@ -1381,7 +1383,7 @@ export const codecForMerchantInfo = (): Codec => export const codecForTax = (): Codec => buildCodecForObject() .property("name", codecForString()) - .property("tax", codecForString()) + .property("tax", codecForAmountString()) .build("Tax"); export const codecForInternationalizedString = @@ -1397,7 +1399,7 @@ export const codecForProduct = (): Codec => ) .property("quantity", codecOptional(codecForNumber())) .property("unit", codecOptional(codecForString())) - .property("price", codecOptional(codecForString())) + .property("price", codecOptional(codecForAmountString())) .build("Tax"); export const codecForMerchantContractTerms = (): Codec => @@ -1436,7 +1438,7 @@ export const codecForMerchantContractTerms = (): Codec => export const codecForPeerContractTerms = (): Codec => buildCodecForObject() .property("summary", codecForString()) - .property("amount", codecForString()) + .property("amount", codecForAmountString()) .property("purse_expiration", codecForTimestamp) .build("PeerContractTerms"); @@ -1624,7 +1626,7 @@ export const codecForMerchantCoinRefundSuccessStatus = .property("exchange_status", codecForConstNumber(200)) .property("exchange_sig", codecForString()) .property("rtransaction_id", codecForNumber()) - .property("refund_amount", codecForString()) + .property("refund_amount", codecForAmountString()) .property("exchange_pub", codecForString()) .property("execution_time", codecForTimestamp) .build("MerchantCoinRefundSuccessStatus"); @@ -1636,7 +1638,7 @@ export const codecForMerchantCoinRefundFailureStatus = .property("coin_pub", codecForString()) .property("exchange_status", codecForNumber()) .property("rtransaction_id", codecForNumber()) - .property("refund_amount", codecForString()) + .property("refund_amount", codecForAmountString()) .property("exchange_code", codecOptional(codecForNumber())) .property("exchange_reply", codecOptional(codecForAny())) .property("execution_time", codecForTimestamp) @@ -1653,8 +1655,8 @@ export const codecForMerchantCoinRefundStatus = export const codecForMerchantOrderStatusPaid = (): Codec => buildCodecForObject() - .property("refund_amount", codecForString()) - .property("refund_taken", codecForString()) + .property("refund_amount", codecForAmountString()) + .property("refund_taken", codecForAmountString()) .property("refund_pending", codecForBoolean()) .property("refunded", codecForBoolean()) .build("MerchantOrderStatusPaid"); @@ -1663,7 +1665,7 @@ export const codecForMerchantOrderRefundPickupResponse = (): Codec => buildCodecForObject() .property("merchant_pub", codecForString()) - .property("refund_amount", codecForString()) + .property("refund_amount", codecForAmountString()) .property("refunds", codecForList(codecForMerchantCoinRefundStatus())) .build("MerchantOrderRefundPickupResponse"); diff --git a/packages/taler-util/src/taleruri.test.ts b/packages/taler-util/src/taleruri.test.ts index 19b94e191..318f460da 100644 --- a/packages/taler-util/src/taleruri.test.ts +++ b/packages/taler-util/src/taleruri.test.ts @@ -29,6 +29,7 @@ import { stringifyRestoreUri, stringifyWithdrawExchange, } from "./taleruri.js"; +import { AmountString } from "./taler-types.js"; test("taler pay url parsing: wrong scheme", (t) => { const url1 = "talerfoo://"; @@ -363,7 +364,7 @@ test("taler withdraw exchange URI with amount (stringify)", (t) => { const url = stringifyWithdrawExchange({ exchangeBaseUrl: "https://exchange.demo.taler.net", exchangePub: "GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0", - amount: "KUDOS:19", + amount: "KUDOS:19" as AmountString, }); t.deepEqual( url, diff --git a/packages/taler-util/src/taleruri.ts b/packages/taler-util/src/taleruri.ts index 310986eaf..9568636b8 100644 --- a/packages/taler-util/src/taleruri.ts +++ b/packages/taler-util/src/taleruri.ts @@ -467,7 +467,7 @@ export function parseWithdrawExchangeUri( `${pi.innerProto}://${hostAndSegments}/`, ); const q = new URLSearchParams(c[1] ?? ""); - const amount = q.get("a") ?? undefined; + const amount = (q.get("a") ?? undefined) as AmountString | undefined; return { type: TalerUriAction.WithdrawExchange, diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index de9948ea6..11567b624 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -475,10 +475,10 @@ export interface BalancesResponse { export const codecForBalance = (): Codec => buildCodecForObject() .property("scopeInfo", codecForAny()) // FIXME - .property("available", codecForString()) + .property("available", codecForAmountString()) .property("hasPendingTransactions", codecForBoolean()) - .property("pendingIncoming", codecForString()) - .property("pendingOutgoing", codecForString()) + .property("pendingIncoming", codecForAmountString()) + .property("pendingOutgoing", codecForAmountString()) .property("requiresUserInput", codecForBoolean()) .build("Balance"); @@ -557,11 +557,11 @@ export interface CoinDumpJson { withdrawal_reserve_pub: string | undefined; coin_status: CoinStatus; spend_allocation: - | { - id: string; - amount: string; - } - | undefined; + | { + id: string; + amount: string; + } + | undefined; /** * Information about the age restriction */ -- cgit v1.2.3