From 708cf016e4ab1e749b86151aa2a9cc548675d63c Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 22 May 2023 13:13:40 -0300 Subject: nominal typing for taskId, also fixing transactionId reference --- .../taler-wallet-core/src/operations/common.ts | 10 +- .../src/operations/pay-merchant.ts | 31 ++++- .../taler-wallet-core/src/operations/pay-peer.ts | 12 +- .../taler-wallet-core/src/operations/pending.ts | 5 +- .../taler-wallet-core/src/operations/refresh.ts | 8 +- packages/taler-wallet-core/src/operations/tip.ts | 8 +- .../src/operations/transactions.ts | 146 +++++++++++---------- .../taler-wallet-core/src/operations/withdraw.ts | 30 +++-- packages/taler-wallet-core/src/pending-types.ts | 5 +- packages/taler-wallet-core/src/util/retries.ts | 88 ++++++------- 10 files changed, 195 insertions(+), 148 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts index 55015f2e0..c3dc622d7 100644 --- a/packages/taler-wallet-core/src/operations/common.ts +++ b/packages/taler-wallet-core/src/operations/common.ts @@ -54,6 +54,7 @@ import { RetryInfo, } from "../util/retries.js"; import { CryptoApiStoppedError } from "../crypto/workers/crypto-dispatcher.js"; +import { TaskId } from "../pending-types.js"; const logger = new Logger("operations/common.ts"); @@ -260,7 +261,7 @@ export async function storeOperationPending( export async function runOperationWithErrorReporting( ws: InternalWalletState, - opId: string, + opId: TaskId, f: () => Promise>, ): Promise> { let maybeError: TalerErrorDetail | undefined; @@ -369,7 +370,7 @@ export enum TombstoneTag { export function makeTransactionId( type: TransactionType, ...args: string[] -): TransactionIdStr { +): string { return `txn:${type}:${args.map((x) => encodeURIComponent(x)).join(":")}`; } @@ -401,10 +402,7 @@ export function parseId( /** * Create an event ID from the type and the primary key for the event. */ -export function makeTombstoneId( - type: TombstoneTag, - ...args: string[] -): TombstoneIdStr { +export function makeTombstoneId(type: TombstoneTag, ...args: string[]): string { return `tmb:${type}:${args.map((x) => encodeURIComponent(x)).join(":")}`; } diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts index 733da8394..b39d5f8c1 100644 --- a/packages/taler-wallet-core/src/operations/pay-merchant.ts +++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts @@ -844,7 +844,11 @@ async function handleInsufficientFunds( payInfo.payCoinSelectionUid = encodeCrock(getRandomBytes(32)); await tx.purchases.put(p); await spendCoins(ws, tx, { - allocationId: `txn:proposal:${p.proposalId}`, + // allocationId: `txn:proposal:${p.proposalId}`, + allocationId: constructTransactionIdentifier({ + tag: TransactionType.Payment, + proposalId: proposalId, + }), coinPubs: payInfo.payCoinSelection.coinPubs, contributions: payInfo.payCoinSelection.coinContributions.map((x) => Amounts.parseOrThrow(x), @@ -1199,7 +1203,10 @@ export async function runPayForConfirmPay( return { type: ConfirmPayResultType.Done, contractTerms: d.contractTermsRaw, - transactionId: makeTransactionId(TransactionType.Payment, proposalId), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.Payment, + proposalId, + }), }; } case OperationAttemptResultType.Error: { @@ -1210,14 +1217,20 @@ export async function runPayForConfirmPay( return { type: ConfirmPayResultType.Pending, lastError: opRetry?.lastError, - transactionId: makeTransactionId(TransactionType.Payment, proposalId), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.Payment, + proposalId, + }), }; } case OperationAttemptResultType.Pending: logger.trace("reporting pending as confirmPay response"); return { type: ConfirmPayResultType.Pending, - transactionId: makeTransactionId(TransactionType.Payment, proposalId), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.Payment, + proposalId, + }), lastError: undefined, }; case OperationAttemptResultType.Longpoll: @@ -1344,7 +1357,11 @@ export async function confirmPay( p.purchaseStatus = PurchaseStatus.Paying; await tx.purchases.put(p); await spendCoins(ws, tx, { - allocationId: `txn:proposal:${p.proposalId}`, + //`txn:proposal:${p.proposalId}` + allocationId: constructTransactionIdentifier({ + tag: TransactionType.Payment, + proposalId: proposalId, + }), coinPubs: coinSelection.coinPubs, contributions: coinSelection.coinContributions.map((x) => Amounts.parseOrThrow(x), @@ -2072,7 +2089,7 @@ export async function startRefundQueryForUri( await startQueryRefund(ws, proposalId); return { transactionId, - } + }; } export async function startQueryRefund( @@ -2357,6 +2374,6 @@ export function computeRefundTransactionState( case RefundGroupStatus.Pending: return { major: TransactionMajorState.Pending, - } + }; } } diff --git a/packages/taler-wallet-core/src/operations/pay-peer.ts b/packages/taler-wallet-core/src/operations/pay-peer.ts index 3b4572900..d9db60e83 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer.ts @@ -705,7 +705,11 @@ export async function initiatePeerPushDebit( // we might want to mark the coins as used and spend them // after we've been able to create the purse. await spendCoins(ws, tx, { - allocationId: `txn:peer-push-debit:${pursePair.pub}`, + // allocationId: `txn:peer-push-debit:${pursePair.pub}`, + allocationId: constructTransactionIdentifier({ + tag: TransactionType.PeerPushDebit, + pursePub: pursePair.pub, + }), coinPubs: sel.coins.map((x) => x.coinPub), contributions: sel.coins.map((x) => Amounts.parseOrThrow(x.contribution), @@ -1280,7 +1284,11 @@ export async function confirmPeerPullDebit( ]) .runReadWrite(async (tx) => { await spendCoins(ws, tx, { - allocationId: `txn:peer-pull-debit:${req.peerPullPaymentIncomingId}`, + // allocationId: `txn:peer-pull-debit:${req.peerPullPaymentIncomingId}`, + allocationId: constructTransactionIdentifier({ + tag: TransactionType.PeerPullDebit, + peerPullPaymentIncomingId: req.peerPullPaymentIncomingId, + }), coinPubs: sel.coins.map((x) => x.coinPub), contributions: sel.coins.map((x) => Amounts.parseOrThrow(x.contribution), diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts index 084f807f2..25d58d8e6 100644 --- a/packages/taler-wallet-core/src/operations/pending.ts +++ b/packages/taler-wallet-core/src/operations/pending.ts @@ -36,6 +36,7 @@ import { import { PendingOperationsResponse, PendingTaskType, + TaskId, } from "../pending-types.js"; import { AbsoluteTime } from "@gnu-taler/taler-util"; import { InternalWalletState } from "../internal-wallet-state.js"; @@ -45,10 +46,10 @@ import { GlobalIDB } from "@gnu-taler/idb-bridge"; function getPendingCommon( ws: InternalWalletState, - opTag: string, + opTag: TaskId, timestampDue: AbsoluteTime, ): { - id: string; + id: TaskId; isDue: boolean; timestampDue: AbsoluteTime; isLongpolling: boolean; diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index 843f37c8e..14556f3c0 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -935,7 +935,7 @@ export async function calculateRefreshOutput( return { outputPerCoin: estimatedOutputPerCoin, - } + }; } async function applyRefresh( @@ -990,7 +990,11 @@ async function applyRefresh( if (!coin.spendAllocation) { coin.spendAllocation = { amount: Amounts.stringify(ocp.amount), - id: `txn:refresh:${refreshGroupId}`, + // id: `txn:refresh:${refreshGroupId}`, + id: constructTransactionIdentifier({ + tag: TransactionType.Refresh, + refreshGroupId, + }), }; } await tx.coins.put(coin); diff --git a/packages/taler-wallet-core/src/operations/tip.ts b/packages/taler-wallet-core/src/operations/tip.ts index 5bcf609b5..4139234f4 100644 --- a/packages/taler-wallet-core/src/operations/tip.ts +++ b/packages/taler-wallet-core/src/operations/tip.ts @@ -67,6 +67,7 @@ import { updateWithdrawalDenoms, } from "./withdraw.js"; import { selectWithdrawalDenominations } from "../util/coinSelection.js"; +import { constructTransactionIdentifier } from "./transactions.js"; const logger = new Logger("operations/tip.ts"); @@ -86,7 +87,7 @@ export function computeTipTransactionStatus( return { major: TransactionMajorState.Pending, minor: TransactionMinorState.Pickup, - }; + }; } return { major: TransactionMajorState.Pending, @@ -395,7 +396,10 @@ export async function acceptTip( //FIXME: if tip is not found the behavior of the function is the same // as the tip was found and finished return { - transactionId: makeTransactionId(TransactionType.Tip, tipId), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.Tip, + walletTipId: tipId, + }), next_url: found?.next_url, }; } diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index a89557c1d..551e495dc 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -31,6 +31,8 @@ import { PeerContractTerms, RefundInfoShort, RefundPaymentInfo, + stringifyPayPullUri, + stringifyPayPushUri, TalerErrorCode, TalerProtocolTimestamp, Transaction, @@ -94,8 +96,17 @@ import { extractContractData, processPurchasePay, } from "./pay-merchant.js"; -import { computePeerPullCreditTransactionState, computePeerPullDebitTransactionState, computePeerPushCreditTransactionState, computePeerPushDebitTransactionState, processPeerPullCredit } from "./pay-peer.js"; -import { computeRefreshTransactionState, processRefreshGroup } from "./refresh.js"; +import { + computePeerPullCreditTransactionState, + computePeerPullDebitTransactionState, + computePeerPushCreditTransactionState, + computePeerPushDebitTransactionState, + processPeerPullCredit, +} from "./pay-peer.js"; +import { + computeRefreshTransactionState, + processRefreshGroup, +} from "./refresh.js"; import { computeTipTransactionStatus, processTip } from "./tip.js"; import { abortWithdrawalTransaction, @@ -378,14 +389,14 @@ function buildTransactionForPushPaymentDebit( : ExtendedStatus.Done, pending: pi.status != PeerPushPaymentInitiationStatus.Done, timestamp: pi.timestampCreated, - talerUri: constructPayPushUri({ + talerUri: stringifyPayPushUri({ exchangeBaseUrl: pi.exchangeBaseUrl, contractPriv: pi.contractPriv, }), - transactionId: makeTransactionId( - TransactionType.PeerPushDebit, - pi.pursePub, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.PeerPushDebit, + pursePub: pi.pursePub, + }), ...(ort?.lastError ? { error: ort.lastError } : {}), }; } @@ -410,10 +421,10 @@ function buildTransactionForPullPaymentDebit( summary: pi.contractTerms.summary, }, timestamp: pi.timestampCreated, - transactionId: makeTransactionId( - TransactionType.PeerPullDebit, - pi.peerPullPaymentIncomingId, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.PeerPullDebit, + peerPullPaymentIncomingId: pi.peerPullPaymentIncomingId, + }), ...(ort?.lastError ? { error: ort.lastError } : {}), }; } @@ -460,14 +471,14 @@ function buildTransactionForPeerPullCredit( expiration: wsr.wgInfo.contractTerms.purse_expiration, summary: wsr.wgInfo.contractTerms.summary, }, - talerUri: constructPayPullUri({ + talerUri: stringifyPayPullUri({ exchangeBaseUrl: wsr.exchangeBaseUrl, contractPriv: wsr.wgInfo.contractPriv, }), - transactionId: makeTransactionId( - TransactionType.PeerPullCredit, - pullCredit.pursePub, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.PeerPullCredit, + pursePub: pullCredit.pursePub, + }), frozen: false, ...(wsrOrt?.lastError ? { @@ -493,14 +504,14 @@ function buildTransactionForPeerPullCredit( expiration: peerContractTerms.purse_expiration, summary: peerContractTerms.summary, }, - talerUri: constructPayPullUri({ + talerUri: stringifyPayPullUri({ exchangeBaseUrl: pullCredit.exchangeBaseUrl, contractPriv: pullCredit.contractPriv, }), - transactionId: makeTransactionId( - TransactionType.PeerPullCredit, - pullCredit.pursePub, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.PeerPullCredit, + pursePub: pullCredit.pursePub, + }), frozen: false, ...(pullCreditOrt?.lastError ? { error: pullCreditOrt.lastError } : {}), }; @@ -533,10 +544,10 @@ function buildTransactionForPeerPushCredit( : ExtendedStatus.Pending, pending: !wsr.timestampFinish, timestamp: wsr.timestampStart, - transactionId: makeTransactionId( - TransactionType.PeerPushCredit, - pushInc.peerPushPaymentIncomingId, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.PeerPushCredit, + peerPushPaymentIncomingId: pushInc.peerPushPaymentIncomingId, + }), frozen: false, ...(wsrOrt?.lastError ? { error: wsrOrt.lastError } : {}), }; @@ -556,10 +567,10 @@ function buildTransactionForPeerPushCredit( extendedStatus: ExtendedStatus.Pending, pending: true, timestamp: pushInc.timestamp, - transactionId: makeTransactionId( - TransactionType.PeerPushCredit, - pushInc.peerPushPaymentIncomingId, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.PeerPushCredit, + peerPushPaymentIncomingId: pushInc.peerPushPaymentIncomingId, + }), frozen: false, ...(pushOrt?.lastError ? { error: pushOrt.lastError } : {}), }; @@ -592,10 +603,10 @@ function buildTransactionForBankIntegratedWithdraw( : ExtendedStatus.Pending, pending: !wgRecord.timestampFinish, timestamp: wgRecord.timestampStart, - transactionId: makeTransactionId( - TransactionType.Withdrawal, - wgRecord.withdrawalGroupId, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.Withdrawal, + withdrawalGroupId: wgRecord.withdrawalGroupId, + }), frozen: false, ...(ort?.lastError ? { error: ort.lastError } : {}), }; @@ -639,10 +650,10 @@ function buildTransactionForManualWithdraw( : ExtendedStatus.Pending, pending: !withdrawalGroup.timestampFinish, timestamp: withdrawalGroup.timestampStart, - transactionId: makeTransactionId( - TransactionType.Withdrawal, - withdrawalGroup.withdrawalGroupId, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.Withdrawal, + withdrawalGroupId: withdrawalGroup.withdrawalGroupId, + }), frozen: false, ...(ort?.lastError ? { error: ort.lastError } : {}), }; @@ -668,7 +679,7 @@ function buildTransactionForRefund( amountRaw: refundRecord.amountRaw, refundedTransactionId: constructTransactionIdentifier({ tag: TransactionType.Payment, - proposalId: refundRecord.proposalId + proposalId: refundRecord.proposalId, }), timestamp: refundRecord.timestampCreated, transactionId: constructTransactionIdentifier({ @@ -680,7 +691,7 @@ function buildTransactionForRefund( frozen: false, pending: false, paymentInfo, - } + }; } function buildTransactionForRefresh( @@ -726,10 +737,10 @@ function buildTransactionForRefresh( : ExtendedStatus.Pending, pending: extendedStatus == ExtendedStatus.Pending, timestamp: refreshGroupRecord.timestampCreated, - transactionId: makeTransactionId( - TransactionType.Refresh, - refreshGroupRecord.refreshGroupId, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.Refresh, + refreshGroupId: refreshGroupRecord.refreshGroupId, + }), frozen: false, ...(ort?.lastError ? { error: ort.lastError } : {}), }; @@ -759,10 +770,10 @@ function buildTransactionForDeposit( timestamp: dg.timestampCreated, targetPaytoUri: dg.wire.payto_uri, wireTransferDeadline: dg.contractTermsRaw.wire_transfer_deadline, - transactionId: makeTransactionId( - TransactionType.Deposit, - dg.depositGroupId, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.Deposit, + depositGroupId: dg.depositGroupId, + }), wireTransferProgress: (100 * dg.transactionPerCoin.reduce( @@ -794,16 +805,15 @@ function buildTransactionForTip( pending: !tipRecord.pickedUpTimestamp, frozen: false, timestamp: tipRecord.acceptedTimestamp, - transactionId: makeTransactionId( - TransactionType.Tip, - tipRecord.walletTipId, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.Tip, + walletTipId: tipRecord.walletTipId, + }), merchantBaseUrl: tipRecord.merchantBaseUrl, ...(ort?.lastError ? { error: ort.lastError } : {}), }; } - async function buildTransactionForPurchase( purchaseRecord: PurchaseRecord, contractData: WalletContractData, @@ -876,17 +886,17 @@ async function buildTransactionForPurchase( refunds, posConfirmation: purchaseRecord.posConfirmation, timestamp, - transactionId: makeTransactionId( - TransactionType.Payment, - purchaseRecord.proposalId, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.Payment, + proposalId: purchaseRecord.proposalId, + }), proposalId: purchaseRecord.proposalId, info, refundQueryActive: purchaseRecord.purchaseStatus === PurchaseStatus.QueryingRefund, frozen: - purchaseRecord.purchaseStatus === PurchaseStatus.AbortedIncompletePayment ?? - false, + purchaseRecord.purchaseStatus === + PurchaseStatus.AbortedIncompletePayment ?? false, ...(ort?.lastError ? { error: ort.lastError } : {}), }; } @@ -1253,25 +1263,25 @@ export function constructTransactionIdentifier( ): TransactionIdStr { switch (pTxId.tag) { case TransactionType.Deposit: - return `txn:${pTxId.tag}:${pTxId.depositGroupId}`; + return `txn:${pTxId.tag}:${pTxId.depositGroupId}` as TransactionIdStr; case TransactionType.Payment: - return `txn:${pTxId.tag}:${pTxId.proposalId}`; + return `txn:${pTxId.tag}:${pTxId.proposalId}` as TransactionIdStr; case TransactionType.PeerPullCredit: - return `txn:${pTxId.tag}:${pTxId.pursePub}`; + return `txn:${pTxId.tag}:${pTxId.pursePub}` as TransactionIdStr; case TransactionType.PeerPullDebit: - return `txn:${pTxId.tag}:${pTxId.peerPullPaymentIncomingId}`; + return `txn:${pTxId.tag}:${pTxId.peerPullPaymentIncomingId}` as TransactionIdStr; case TransactionType.PeerPushCredit: - return `txn:${pTxId.tag}:${pTxId.peerPushPaymentIncomingId}`; + return `txn:${pTxId.tag}:${pTxId.peerPushPaymentIncomingId}` as TransactionIdStr; case TransactionType.PeerPushDebit: - return `txn:${pTxId.tag}:${pTxId.pursePub}`; + return `txn:${pTxId.tag}:${pTxId.pursePub}` as TransactionIdStr; case TransactionType.Refresh: - return `txn:${pTxId.tag}:${pTxId.refreshGroupId}`; + return `txn:${pTxId.tag}:${pTxId.refreshGroupId}` as TransactionIdStr; case TransactionType.Refund: - return `txn:${pTxId.tag}:${pTxId.refundGroupId}`; + return `txn:${pTxId.tag}:${pTxId.refundGroupId}` as TransactionIdStr; case TransactionType.Tip: - return `txn:${pTxId.tag}:${pTxId.walletTipId}`; + return `txn:${pTxId.tag}:${pTxId.walletTipId}` as TransactionIdStr; case TransactionType.Withdrawal: - return `txn:${pTxId.tag}:${pTxId.withdrawalGroupId}`; + return `txn:${pTxId.tag}:${pTxId.withdrawalGroupId}` as TransactionIdStr; default: assertUnreachable(pTxId); } diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index d0c4d453f..ba154d05c 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -482,7 +482,7 @@ export function computeWithdrawalTransactionStatus( return { major: TransactionMajorState.Aborted, minor: TransactionMinorState.Exchange, - } + }; } } @@ -1997,7 +1997,7 @@ async function processReserveBankStatus( return { oldTxState, newTxState, - } + }; }); notifyTransition(ws, transactionId, transitionInfo); return { @@ -2059,7 +2059,7 @@ async function processReserveBankStatus( return { oldTxState, newTxState, - } + }; }); notifyTransition(ws, transactionId, transitionInfo); @@ -2208,12 +2208,12 @@ export async function internalCreateWithdrawalGroup( const oldTxState = { major: TransactionMajorState.None, - } + }; const newTxState = computeWithdrawalTransactionStatus(withdrawalGroup); return { oldTxState, newTxState, - } + }; }); notifyTransition(ws, transactionId, transitionInfo); @@ -2253,10 +2253,10 @@ export async function acceptWithdrawalFromUri( return { reservePub: existingWithdrawalGroup.reservePub, confirmTransferUrl: url, - transactionId: makeTransactionId( - TransactionType.Withdrawal, - existingWithdrawalGroup.withdrawalGroupId, - ), + transactionId: constructTransactionIdentifier({ + tag: TransactionType.Withdrawal, + withdrawalGroupId: existingWithdrawalGroup.withdrawalGroupId, + }), }; } @@ -2290,8 +2290,8 @@ export async function acceptWithdrawalFromUri( }); const withdrawalGroupId = withdrawalGroup.withdrawalGroupId; - const transactionId = constructTaskIdentifier({ - tag: PendingTaskType.Withdraw, + const transactionId = constructTransactionIdentifier({ + tag: TransactionType.Withdrawal, withdrawalGroupId, }); @@ -2301,7 +2301,9 @@ export async function acceptWithdrawalFromUri( const processedWithdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, { withdrawalGroupId, }); - if (processedWithdrawalGroup?.status === WithdrawalGroupStatus.FailedBankAborted) { + if ( + processedWithdrawalGroup?.status === WithdrawalGroupStatus.FailedBankAborted + ) { throw TalerError.fromDetail( TalerErrorCode.WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK, {}, @@ -2346,8 +2348,8 @@ export async function createManualWithdrawal( }); const withdrawalGroupId = withdrawalGroup.withdrawalGroupId; - const transactionId = constructTaskIdentifier({ - tag: PendingTaskType.Withdraw, + const transactionId = constructTransactionIdentifier({ + tag: TransactionType.Withdrawal, withdrawalGroupId, }); diff --git a/packages/taler-wallet-core/src/pending-types.ts b/packages/taler-wallet-core/src/pending-types.ts index 23f9ae21f..e85f0d460 100644 --- a/packages/taler-wallet-core/src/pending-types.ts +++ b/packages/taler-wallet-core/src/pending-types.ts @@ -191,6 +191,9 @@ export interface PendingDepositTask { depositGroupId: string; } +declare const __taskId: unique symbol; +export type TaskId = string & { [__taskId]: true }; + /** * Fields that are present in every pending operation. */ @@ -203,7 +206,7 @@ export interface PendingTaskInfoCommon { /** * Unique identifier for the pending task. */ - id: string; + id: TaskId; /** * Set to true if the operation indicates that something is really in progress, diff --git a/packages/taler-wallet-core/src/util/retries.ts b/packages/taler-wallet-core/src/util/retries.ts index 7607a6583..d4bd1c05f 100644 --- a/packages/taler-wallet-core/src/util/retries.ts +++ b/packages/taler-wallet-core/src/util/retries.ts @@ -44,7 +44,7 @@ import { } from "../db.js"; import { TalerError } from "@gnu-taler/taler-util"; import { InternalWalletState } from "../internal-wallet-state.js"; -import { PendingTaskType } from "../pending-types.js"; +import { PendingTaskType, TaskId } from "../pending-types.js"; import { GetReadWriteAccess } from "./query.js"; import { assertUnreachable } from "./assertUnreachable.js"; @@ -79,7 +79,7 @@ export namespace OperationAttemptResult { export function longpoll(): OperationAttemptResult { return { type: OperationAttemptResultType.Longpoll, - } + }; } } @@ -214,89 +214,89 @@ export function parseTaskIdentifier(x: string): ParsedTaskIdentifier { throw Error("not yet implemented"); } -export function constructTaskIdentifier(p: ParsedTaskIdentifier): string { +export function constructTaskIdentifier(p: ParsedTaskIdentifier): TaskId { switch (p.tag) { case PendingTaskType.Backup: - return `${p.tag}:${p.backupProviderBaseUrl}`; + return `${p.tag}:${p.backupProviderBaseUrl}` as TaskId; case PendingTaskType.Deposit: - return `${p.tag}:${p.depositGroupId}`; + return `${p.tag}:${p.depositGroupId}` as TaskId; case PendingTaskType.ExchangeCheckRefresh: - return `${p.tag}:${p.exchangeBaseUrl}`; + return `${p.tag}:${p.exchangeBaseUrl}` as TaskId; case PendingTaskType.ExchangeUpdate: - return `${p.tag}:${p.exchangeBaseUrl}`; + return `${p.tag}:${p.exchangeBaseUrl}` as TaskId; case PendingTaskType.PeerPullDebit: - return `${p.tag}:${p.peerPullPaymentIncomingId}`; + return `${p.tag}:${p.peerPullPaymentIncomingId}` as TaskId; case PendingTaskType.PeerPushCredit: - return `${p.tag}:${p.peerPushPaymentIncomingId}`; + return `${p.tag}:${p.peerPushPaymentIncomingId}` as TaskId; case PendingTaskType.PeerPullCredit: - return `${p.tag}:${p.pursePub}`; + return `${p.tag}:${p.pursePub}` as TaskId; case PendingTaskType.PeerPushDebit: - return `${p.tag}:${p.pursePub}`; + return `${p.tag}:${p.pursePub}` as TaskId; case PendingTaskType.Purchase: - return `${p.tag}:${p.proposalId}`; + return `${p.tag}:${p.proposalId}` as TaskId; case PendingTaskType.Recoup: - return `${p.tag}:${p.recoupGroupId}`; + return `${p.tag}:${p.recoupGroupId}` as TaskId; case PendingTaskType.Refresh: - return `${p.tag}:${p.refreshGroupId}`; + return `${p.tag}:${p.refreshGroupId}` as TaskId; case PendingTaskType.TipPickup: - return `${p.tag}:${p.walletTipId}`; + return `${p.tag}:${p.walletTipId}` as TaskId; case PendingTaskType.Withdraw: - return `${p.tag}:${p.withdrawalGroupId}`; + return `${p.tag}:${p.withdrawalGroupId}` as TaskId; default: assertUnreachable(p); } } export namespace TaskIdentifiers { - export function forWithdrawal(wg: WithdrawalGroupRecord): string { - return `${PendingTaskType.Withdraw}:${wg.withdrawalGroupId}`; + export function forWithdrawal(wg: WithdrawalGroupRecord): TaskId { + return `${PendingTaskType.Withdraw}:${wg.withdrawalGroupId}` as TaskId; } - export function forExchangeUpdate(exch: ExchangeRecord): string { - return `${PendingTaskType.ExchangeUpdate}:${exch.baseUrl}`; + export function forExchangeUpdate(exch: ExchangeRecord): TaskId { + return `${PendingTaskType.ExchangeUpdate}:${exch.baseUrl}` as TaskId; } - export function forExchangeUpdateFromUrl(exchBaseUrl: string): string { - return `${PendingTaskType.ExchangeUpdate}:${exchBaseUrl}`; + export function forExchangeUpdateFromUrl(exchBaseUrl: string): TaskId { + return `${PendingTaskType.ExchangeUpdate}:${exchBaseUrl}` as TaskId; } - export function forExchangeCheckRefresh(exch: ExchangeRecord): string { - return `${PendingTaskType.ExchangeCheckRefresh}:${exch.baseUrl}`; + export function forExchangeCheckRefresh(exch: ExchangeRecord): TaskId { + return `${PendingTaskType.ExchangeCheckRefresh}:${exch.baseUrl}` as TaskId; } - export function forTipPickup(tipRecord: TipRecord): string { - return `${PendingTaskType.TipPickup}:${tipRecord.walletTipId}`; + export function forTipPickup(tipRecord: TipRecord): TaskId { + return `${PendingTaskType.TipPickup}:${tipRecord.walletTipId}` as TaskId; } - export function forRefresh(refreshGroupRecord: RefreshGroupRecord): string { - return `${PendingTaskType.Refresh}:${refreshGroupRecord.refreshGroupId}`; + export function forRefresh(refreshGroupRecord: RefreshGroupRecord): TaskId { + return `${PendingTaskType.Refresh}:${refreshGroupRecord.refreshGroupId}` as TaskId; } - export function forPay(purchaseRecord: PurchaseRecord): string { - return `${PendingTaskType.Purchase}:${purchaseRecord.proposalId}`; + export function forPay(purchaseRecord: PurchaseRecord): TaskId { + return `${PendingTaskType.Purchase}:${purchaseRecord.proposalId}` as TaskId; } - export function forRecoup(recoupRecord: RecoupGroupRecord): string { - return `${PendingTaskType.Recoup}:${recoupRecord.recoupGroupId}`; + export function forRecoup(recoupRecord: RecoupGroupRecord): TaskId { + return `${PendingTaskType.Recoup}:${recoupRecord.recoupGroupId}` as TaskId; } - export function forDeposit(depositRecord: DepositGroupRecord): string { - return `${PendingTaskType.Deposit}:${depositRecord.depositGroupId}`; + export function forDeposit(depositRecord: DepositGroupRecord): TaskId { + return `${PendingTaskType.Deposit}:${depositRecord.depositGroupId}` as TaskId; } - export function forBackup(backupRecord: BackupProviderRecord): string { - return `${PendingTaskType.Backup}:${backupRecord.baseUrl}`; + export function forBackup(backupRecord: BackupProviderRecord): TaskId { + return `${PendingTaskType.Backup}:${backupRecord.baseUrl}` as TaskId; } export function forPeerPushPaymentInitiation( ppi: PeerPushPaymentInitiationRecord, - ): string { - return `${PendingTaskType.PeerPushDebit}:${ppi.pursePub}`; + ): TaskId { + return `${PendingTaskType.PeerPushDebit}:${ppi.pursePub}` as TaskId; } export function forPeerPullPaymentInitiation( ppi: PeerPullPaymentInitiationRecord, - ): string { - return `${PendingTaskType.PeerPullCredit}:${ppi.pursePub}`; + ): TaskId { + return `${PendingTaskType.PeerPullCredit}:${ppi.pursePub}` as TaskId; } export function forPeerPullPaymentDebit( ppi: PeerPullPaymentIncomingRecord, - ): string { - return `${PendingTaskType.PeerPullDebit}:${ppi.peerPullPaymentIncomingId}`; + ): TaskId { + return `${PendingTaskType.PeerPullDebit}:${ppi.peerPullPaymentIncomingId}` as TaskId; } export function forPeerPushCredit( ppi: PeerPushPaymentIncomingRecord, - ): string { - return `${PendingTaskType.PeerPushCredit}:${ppi.peerPushPaymentIncomingId}`; + ): TaskId { + return `${PendingTaskType.PeerPushCredit}:${ppi.peerPushPaymentIncomingId}` as TaskId; } } -- cgit v1.2.3