From 984cba226ff99d8db3e774f2b0cae5b4b3fa5185 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 22 May 2023 13:12:27 -0300 Subject: [PATCH] transactionIdStr nominal typing --- packages/taler-util/src/wallet-types.ts | 155 +++++++++++++++--------- 1 file changed, 101 insertions(+), 54 deletions(-) diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index bc43652d9..2f9d3bb04 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -30,9 +30,11 @@ import { AmountJson, codecForAmountString } from "./amounts.js"; import { BackupRecovery } from "./backup-types.js"; import { + Codec, + Context, + DecodingError, buildCodecForObject, buildCodecForUnion, - Codec, codecForAny, codecForBoolean, codecForConstString, @@ -42,6 +44,7 @@ import { codecForNumber, codecForString, codecOptional, + renderContext, } from "./codec.js"; import { VersionMatchResult } from "./libtool-version.js"; import { PaytoUri } from "./payto.js"; @@ -50,40 +53,84 @@ import { TalerErrorCode } from "./taler-error-codes.js"; import { AmountString, AuditorDenomSig, - codecForMerchantContractTerms, - codecForPeerContractTerms, CoinEnvelope, - DenominationPubKey, DenomKeyType, + DenominationPubKey, ExchangeAuditor, MerchantContractTerms, PeerContractTerms, - TrackTransaction, UnblindedSignature, + codecForMerchantContractTerms, + codecForPeerContractTerms, } from "./taler-types.js"; import { AbsoluteTime, - codecForAbsoluteTime, - codecForTimestamp, TalerProtocolDuration, TalerProtocolTimestamp, + codecForAbsoluteTime, + codecForTimestamp, } from "./time.js"; -import { - codecForOrderShortInfo, - OrderShortInfo, -} from "./transactions-types.js"; +import { OrderShortInfo } from "./transactions-types.js"; /** * Identifier for a transaction in the wallet. */ -export type TransactionIdStr = `txn:${string}:${string}`; +declare const __txId: unique symbol; +export type TransactionIdStr = `txn:${string}:${string}` & { [__txId]: true }; /** * Identifier for a pending task in the wallet. */ -export type PendingIdStr = `pnd:${string}:${string}`; +declare const __pndId: unique symbol; +export type PendingIdStr = `pnd:${string}:${string}` & { [__pndId]: true }; -export type TombstoneIdStr = `tmb:${string}:${string}`; +declare const __tmbId: unique symbol; +export type TombstoneIdStr = `tmb:${string}:${string}` & { [__tmbId]: true }; + +function codecForTransactionIdStr(): Codec { + return { + decode(x: any, c?: Context): TransactionIdStr { + if (typeof x === "string" && x.startsWith("txn:")) { + return x as TransactionIdStr; + } + throw new DecodingError( + `expected string starting with "txn:" at ${renderContext( + c, + )} but got ${x}`, + ); + }, + }; +} + +function codecForPendingIdStr(): Codec { + return { + decode(x: any, c?: Context): PendingIdStr { + if (typeof x === "string" && x.startsWith("txn:")) { + return x as PendingIdStr; + } + throw new DecodingError( + `expected string starting with "txn:" at ${renderContext( + c, + )} but got ${x}`, + ); + }, + }; +} + +function codecForTombstoneIdStr(): Codec { + return { + decode(x: any, c?: Context): TombstoneIdStr { + if (typeof x === "string" && x.startsWith("tmb:")) { + return x as TombstoneIdStr; + } + throw new DecodingError( + `expected string starting with "tmb:" at ${renderContext( + c, + )} but got ${x}`, + ); + }, + }; +} /** * Response for the create reserve request to the wallet. @@ -257,12 +304,12 @@ export enum ConfirmPayResultType { export interface ConfirmPayResultDone { type: ConfirmPayResultType.Done; contractTerms: MerchantContractTerms; - transactionId: string; + transactionId: TransactionIdStr; } export interface ConfirmPayResultPending { type: ConfirmPayResultType.Pending; - transactionId: string; + transactionId: TransactionIdStr; lastError: TalerErrorDetail | undefined; } @@ -279,14 +326,14 @@ export const codecForConfirmPayResultPending = (): Codec => buildCodecForObject() .property("lastError", codecOptional(codecForTalerErrorDetail())) - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .property("type", codecForConstString(ConfirmPayResultType.Pending)) .build("ConfirmPayResultPending"); export const codecForConfirmPayResultDone = (): Codec => buildCodecForObject() .property("type", codecForConstString(ConfirmPayResultType.Done)) - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .property("contractTerms", codecForMerchantContractTerms()) .build("ConfirmPayResultDone"); @@ -387,7 +434,7 @@ export interface PrepareTipResult { } export interface AcceptTipResponse { - transactionId: string; + transactionId: TransactionIdStr; next_url?: string; } @@ -419,7 +466,7 @@ export const codecForPreparePayResultPaymentPossible = .property("amountEffective", codecForAmountString()) .property("amountRaw", codecForAmountString()) .property("contractTerms", codecForMerchantContractTerms()) - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .property("proposalId", codecForString()) .property("contractTermsHash", codecForString()) .property("talerUri", codecForString()) @@ -495,7 +542,7 @@ export const codecForPreparePayResultInsufficientBalance = .property("contractTerms", codecForAny()) .property("talerUri", codecForString()) .property("proposalId", codecForString()) - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .property("noncePriv", codecForString()) .property( "status", @@ -520,7 +567,7 @@ export const codecForPreparePayResultAlreadyConfirmed = .property("talerUri", codecOptional(codecForString())) .property("contractTerms", codecForAny()) .property("contractTermsHash", codecForString()) - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .property("proposalId", codecForString()) .build("PreparePayResultAlreadyConfirmed"); @@ -554,7 +601,7 @@ export type PreparePayResult = */ export interface PreparePayResultPaymentPossible { status: PreparePayResultType.PaymentPossible; - transactionId: string; + transactionId: TransactionIdStr; /** * @deprecated use transactionId instead */ @@ -569,7 +616,7 @@ export interface PreparePayResultPaymentPossible { export interface PreparePayResultInsufficientBalance { status: PreparePayResultType.InsufficientBalance; - transactionId: string; + transactionId: TransactionIdStr; proposalId: string; contractTerms: MerchantContractTerms; amountRaw: string; @@ -580,7 +627,7 @@ export interface PreparePayResultInsufficientBalance { export interface PreparePayResultAlreadyConfirmed { status: PreparePayResultType.AlreadyConfirmed; - transactionId: string; + transactionId: TransactionIdStr; contractTerms: MerchantContractTerms; paid: boolean; amountRaw: string; @@ -603,7 +650,7 @@ export interface BankWithdrawDetails { export interface AcceptWithdrawalResponse { reservePub: string; confirmTransferUrl?: string; - transactionId: string; + transactionId: TransactionIdStr; } /** @@ -1067,7 +1114,7 @@ export interface AcceptManualWithdrawalResult { */ reservePub: string; - transactionId: string; + transactionId: TransactionIdStr; } export interface ManualWithdrawalDetails { @@ -1362,12 +1409,12 @@ export const codecForAcceptExchangeTosRequest = .build("AcceptExchangeTosRequest"); export interface AcceptRefundRequest { - transactionId: string; + transactionId: TransactionIdStr; } export const codecForApplyRefundRequest = (): Codec => buildCodecForObject() - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .build("AcceptRefundRequest"); export interface ApplyRefundFromPurchaseIdRequest { @@ -1615,7 +1662,7 @@ export interface PrepareRefundRequest { } export interface StartRefundQueryForUriResponse { - transactionId: string; + transactionId: TransactionIdStr; } export const codecForPrepareRefundRequest = (): Codec => @@ -1624,13 +1671,13 @@ export const codecForPrepareRefundRequest = (): Codec => .build("PrepareRefundRequest"); export interface StartRefundQueryRequest { - transactionId: string; + transactionId: TransactionIdStr; } export const codecForStartRefundQueryRequest = (): Codec => buildCodecForObject() - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .build("StartRefundQueryRequest"); export interface PrepareTipRequest { @@ -1639,7 +1686,7 @@ export interface PrepareTipRequest { export const codecForPrepareTipRequest = (): Codec => buildCodecForObject() - .property("talerTipUri", codecForString()) + .property("talerTipUri", codecForTransactionIdStr()) .build("PrepareTipRequest"); export interface AcceptTipRequest { @@ -1652,35 +1699,35 @@ export const codecForAcceptTipRequest = (): Codec => .build("AcceptTipRequest"); export interface SuspendTransactionRequest { - transactionId: string; + transactionId: TransactionIdStr; } export const codecForSuspendTransaction = (): Codec => buildCodecForObject() - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .build("SuspendTransactionRequest"); export interface ResumeTransactionRequest { - transactionId: string; + transactionId: TransactionIdStr; } export const codecForResumeTransaction = (): Codec => buildCodecForObject() - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .build("ResumeTransactionRequest"); export interface AbortTransactionRequest { - transactionId: string; + transactionId: TransactionIdStr; } export interface CancelAbortingTransactionRequest { - transactionId: string; + transactionId: TransactionIdStr; } export const codecForAbortTransaction = (): Codec => buildCodecForObject() - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .build("AbortTransactionRequest"); export interface DepositGroupFees { @@ -1727,11 +1774,11 @@ export const codecForCreateDepositGroupRequest = export interface CreateDepositGroupResponse { depositGroupId: string; - transactionId: string; + transactionId: TransactionIdStr; } export interface TxIdResponse { - transactionId: string; + transactionId: TransactionIdStr; } export interface WithdrawUriInfoResponse { @@ -1762,23 +1809,23 @@ export interface WalletCurrencyInfo { } export interface DeleteTransactionRequest { - transactionId: string; + transactionId: TransactionIdStr; } export interface RetryTransactionRequest { - transactionId: string; + transactionId: TransactionIdStr; } export const codecForDeleteTransactionRequest = (): Codec => buildCodecForObject() - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .build("DeleteTransactionRequest"); export const codecForRetryTransactionRequest = (): Codec => buildCodecForObject() - .property("transactionId", codecForString()) + .property("transactionId", codecForTransactionIdStr()) .build("RetryTransactionRequest"); export interface SetWalletDeviceIdRequest { @@ -1907,12 +1954,12 @@ interface AttentionBackupUnpaid { interface AttentionMerchantRefund { type: AttentionType.MerchantRefund; - transactionId: string; + transactionId: TransactionIdStr; } interface AttentionKycWithdrawal { type: AttentionType.KycWithdrawal; - transactionId: string; + transactionId: TransactionIdStr; } interface AttentionExchangeTosChanged { @@ -1942,12 +1989,12 @@ interface AttentionAuditorDenominationExpires { } interface AttentionPullPaymentPaid { type: AttentionType.PullPaymentPaid; - transactionId: string; + transactionId: TransactionIdStr; } interface AttentionPushPaymentReceived { type: AttentionType.PushPaymentReceived; - transactionId: string; + transactionId: TransactionIdStr; } export type UserAttentionUnreadList = Array<{ @@ -2070,7 +2117,7 @@ export interface InitiatePeerPushDebitResponse { mergePriv: string; contractPriv: string; talerUri: string; - transactionId: string; + transactionId: TransactionIdStr; } export const codecForInitiatePeerPushDebitRequest = @@ -2130,11 +2177,11 @@ export interface ConfirmPeerPushCreditRequest { peerPushPaymentIncomingId: string; } export interface AcceptPeerPushPaymentResponse { - transactionId: string; + transactionId: TransactionIdStr; } export interface AcceptPeerPullPaymentResponse { - transactionId: string; + transactionId: TransactionIdStr; } export const codecForConfirmPeerPushPaymentRequest = @@ -2201,7 +2248,7 @@ export interface InitiatePeerPullCreditResponse { */ talerUri: string; - transactionId: string; + transactionId: TransactionIdStr; } /**