aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/taler-wallet-core/src/operations/common.ts10
-rw-r--r--packages/taler-wallet-core/src/operations/pay-merchant.ts31
-rw-r--r--packages/taler-wallet-core/src/operations/pay-peer.ts12
-rw-r--r--packages/taler-wallet-core/src/operations/pending.ts5
-rw-r--r--packages/taler-wallet-core/src/operations/refresh.ts8
-rw-r--r--packages/taler-wallet-core/src/operations/tip.ts8
-rw-r--r--packages/taler-wallet-core/src/operations/transactions.ts146
-rw-r--r--packages/taler-wallet-core/src/operations/withdraw.ts30
-rw-r--r--packages/taler-wallet-core/src/pending-types.ts5
-rw-r--r--packages/taler-wallet-core/src/util/retries.ts88
10 files changed, 195 insertions, 148 deletions
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<T1, T2>(
ws: InternalWalletState,
- opId: string,
+ opId: TaskId,
f: () => Promise<OperationAttemptResult<T1, T2>>,
): Promise<OperationAttemptResult<T1, T2>> {
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<unknown, unknown> {
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;
}
}