summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src')
-rw-r--r--packages/taler-wallet-core/src/db.ts75
-rw-r--r--packages/taler-wallet-core/src/internal-wallet-state.ts2
-rw-r--r--packages/taler-wallet-core/src/operations/backup/import.ts2
-rw-r--r--packages/taler-wallet-core/src/operations/common.ts2
-rw-r--r--packages/taler-wallet-core/src/operations/deposits.ts4
-rw-r--r--packages/taler-wallet-core/src/operations/pay-merchant.ts3
-rw-r--r--packages/taler-wallet-core/src/operations/pay-peer.ts672
-rw-r--r--packages/taler-wallet-core/src/operations/pending.ts10
-rw-r--r--packages/taler-wallet-core/src/operations/recoup.ts2
-rw-r--r--packages/taler-wallet-core/src/operations/refresh.ts12
-rw-r--r--packages/taler-wallet-core/src/operations/transactions.ts32
-rw-r--r--packages/taler-wallet-core/src/operations/withdraw.ts134
-rw-r--r--packages/taler-wallet-core/src/pending-types.ts9
-rw-r--r--packages/taler-wallet-core/src/util/retries.ts12
-rw-r--r--packages/taler-wallet-core/src/wallet.ts12
15 files changed, 751 insertions, 232 deletions
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
index febc5f8fa..a95db9ca3 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -130,10 +130,10 @@ export enum OperationStatusRange {
// Operations that need to be actively processed.
ACTIVE_START = 10,
ACTIVE_END = 29,
- // Operations that need user input, but nothing can be done
- // automatically.
- USER_ATTENTION_START = 30,
- USER_ATTENTION_END = 49,
+ // Operations that are suspended and might
+ // expire, but nothing else can be done.
+ SUSPENDED_START = 30,
+ SUSPENDED_END = 49,
// Operations that don't need any attention or processing.
DORMANT_START = 50,
DORMANT_END = 69,
@@ -146,24 +146,24 @@ export enum WithdrawalGroupStatus {
/**
* Reserve must be registered with the bank.
*/
- RegisteringBank = 10,
+ PendingRegisteringBank = 10,
/**
* We've registered reserve's information with the bank
* and are now waiting for the user to confirm the withdraw
* with the bank (typically 2nd factor auth).
*/
- WaitConfirmBank = 11,
+ PendingWaitConfirmBank = 11,
/**
* Querying reserve status with the exchange.
*/
- QueryingStatus = 12,
+ PendingQueryingStatus = 12,
/**
* Ready for withdrawal.
*/
- Ready = 13,
+ PendingReady = 13,
/**
* We are telling the bank that we don't want to complete
@@ -174,12 +174,20 @@ export enum WithdrawalGroupStatus {
/**
* Exchange wants KYC info from the user.
*/
- Kyc = 16,
+ PendingKyc = 16,
/**
* Exchange is doing AML checks.
*/
- Aml = 17,
+ PendingAml = 17,
+
+ SuspendedRegisteringBank = 30,
+ SuspendedWaitConfirmBank = 31,
+ SuspendedQueryingStatus = 32,
+ SuspendedReady = 33,
+ SuspendedAbortingBank = 34,
+ SuspendedKyc = 35,
+ SuspendedAml = 36,
/**
* The corresponding withdraw record has been created.
@@ -191,16 +199,16 @@ export enum WithdrawalGroupStatus {
/**
* The bank aborted the withdrawal.
*/
- BankAborted = 51,
+ FailedBankAborted = 51,
- SuspendedRegisteringBank = 52,
- SuspendedWaitConfirmBank = 53,
- SuspendedQueryingStatus = 54,
- SuspendedReady = 55,
- SuspendedAbortingBank = 56,
- SuspendedKyc = 57,
- SuspendedAml = 58,
FailedAbortingBank = 59,
+
+ /**
+ * Aborted in a state where we were supposed to
+ * talk to the exchange. Money might have been
+ * wired or not.
+ */
+ AbortedExchange = 60
}
/**
@@ -1790,8 +1798,18 @@ export enum PeerPushPaymentInitiationStatus {
/**
* Initiated, but no purse created yet.
*/
- Initiated = 10 /* ACTIVE_START */,
- PurseCreated = 50 /* DORMANT_START */,
+ PendingCreatePurse = 10 /* ACTIVE_START */,
+ PendingReady = 11,
+ AbortingDeletePurse = 12,
+ AbortingRefresh = 13,
+
+ SuspendedCreatePurse = 30,
+ SuspendedReady = 31,
+ SuspendedAbortingDeletePurse = 32,
+ SuspendedAbortingRefresh = 33,
+
+ Done = 50 /* DORMANT_START */,
+ Aborted = 51,
}
export interface PeerPushPaymentCoinSelection {
@@ -1856,14 +1874,18 @@ export interface PeerPushPaymentInitiationRecord {
}
export enum PeerPullPaymentInitiationStatus {
- Initial = 10 /* ACTIVE_START */,
+ PendingCreatePurse = 10 /* ACTIVE_START */,
/**
* Purse created, waiting for the other party to accept the
* invoice and deposit money into it.
*/
- PurseCreated = 11 /* ACTIVE_START + 1 */,
- KycRequired = 12 /* ACTIVE_START + 2 */,
- PurseDeposited = 50 /* DORMANT_START */,
+ PendingReady = 11 /* ACTIVE_START + 1 */,
+ PendingMergeKycRequired = 12 /* ACTIVE_START + 2 */,
+ PendingWithdrawing = 13,
+ SuspendedCreatePurse = 30,
+ SuspendedReady = 31,
+ SuspendedWithdrawing = 32,
+ DonePurseDeposited = 50 /* DORMANT_START */,
}
export interface PeerPullPaymentInitiationRecord {
@@ -1921,12 +1943,13 @@ export interface PeerPullPaymentInitiationRecord {
export enum PeerPushPaymentIncomingStatus {
Proposed = 30 /* USER_ATTENTION_START */,
Accepted = 10 /* ACTIVE_START */,
- KycRequired = 11 /* ACTIVE_START + 1 */,
+ MergeKycRequired = 11 /* ACTIVE_START + 1 */,
/**
* Merge was successful and withdrawal group has been created, now
* everything is in the hand of the withdrawal group.
*/
- WithdrawalCreated = 50 /* DORMANT_START */,
+ Withdrawing = 12,
+ Done = 50 /* DORMANT_START */,
}
/**
diff --git a/packages/taler-wallet-core/src/internal-wallet-state.ts b/packages/taler-wallet-core/src/internal-wallet-state.ts
index e59781471..760f40d6c 100644
--- a/packages/taler-wallet-core/src/internal-wallet-state.ts
+++ b/packages/taler-wallet-core/src/internal-wallet-state.ts
@@ -177,7 +177,7 @@ export interface InternalWalletState {
*
* Used to allow processing of new work faster.
*/
- latch: AsyncCondition;
+ workAvailable: AsyncCondition;
listeners: NotificationListener[];
diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts
index 32b90e126..296517162 100644
--- a/packages/taler-wallet-core/src/operations/backup/import.ts
+++ b/packages/taler-wallet-core/src/operations/backup/import.ts
@@ -553,7 +553,7 @@ export async function importBackup(
reservePub,
status: backupWg.timestamp_finish
? WithdrawalGroupStatus.Finished
- : WithdrawalGroupStatus.QueryingStatus, // FIXME!
+ : WithdrawalGroupStatus.PendingQueryingStatus, // FIXME!
timestampStart: backupWg.timestamp_created,
wgInfo,
restrictAge: backupWg.restrict_age,
diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts
index 539632b02..55015f2e0 100644
--- a/packages/taler-wallet-core/src/operations/common.ts
+++ b/packages/taler-wallet-core/src/operations/common.ts
@@ -492,7 +492,7 @@ export function runLongpollAsync(
if (!res.ready) {
await storeOperationPending(ws, retryTag);
}
- ws.latch.trigger();
+ ws.workAvailable.trigger();
};
asyncFn();
}
diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts
index e1d699775..b08f03bd1 100644
--- a/packages/taler-wallet-core/src/operations/deposits.ts
+++ b/packages/taler-wallet-core/src/operations/deposits.ts
@@ -248,7 +248,7 @@ export async function resumeDepositGroup(
}
return undefined;
});
- ws.latch.trigger();
+ ws.workAvailable.trigger();
if (res) {
ws.notify({
type: NotificationType.TransactionStateTransition,
@@ -301,7 +301,7 @@ export async function abortDepositGroup(
});
stopLongpolling(ws, retryTag);
// Need to process the operation again.
- ws.latch.trigger();
+ ws.workAvailable.trigger();
if (res) {
ws.notify({
type: NotificationType.TransactionStateTransition,
diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts
index d2713dc9d..67343d69a 100644
--- a/packages/taler-wallet-core/src/operations/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts
@@ -2410,7 +2410,7 @@ export async function processPurchaseQueryRefund(
return OperationAttemptResult.finishedEmpty();
}
-export async function abortPay(
+export async function abortPayMerchant(
ws: InternalWalletState,
proposalId: string,
cancelImmediately?: boolean,
@@ -2499,6 +2499,7 @@ export function computePayMerchantTransactionState(
case PurchaseStatus.Proposed:
return {
major: TransactionMajorState.Dialog,
+ minor: TransactionMinorState.MerchantOrderProposed,
};
case PurchaseStatus.ProposalDownloadFailed:
return {
diff --git a/packages/taler-wallet-core/src/operations/pay-peer.ts b/packages/taler-wallet-core/src/operations/pay-peer.ts
index 33659afe0..31e395cab 100644
--- a/packages/taler-wallet-core/src/operations/pay-peer.ts
+++ b/packages/taler-wallet-core/src/operations/pay-peer.ts
@@ -75,20 +75,21 @@ import {
NotificationType,
HttpStatusCode,
codecForWalletKycUuid,
- WalletKycUuid,
+ TransactionState,
+ TransactionMajorState,
+ TransactionMinorState,
} from "@gnu-taler/taler-util";
import { SpendCoinDetails } from "../crypto/cryptoImplementation.js";
import {
DenominationRecord,
- KycPendingInfo,
- KycUserType,
- OperationStatus,
+ PeerPullPaymentIncomingRecord,
PeerPullPaymentIncomingStatus,
PeerPullPaymentInitiationRecord,
PeerPullPaymentInitiationStatus,
PeerPushPaymentCoinSelection,
PeerPushPaymentIncomingRecord,
PeerPushPaymentIncomingStatus,
+ PeerPushPaymentInitiationRecord,
PeerPushPaymentInitiationStatus,
ReserveRecord,
WithdrawalGroupStatus,
@@ -98,7 +99,6 @@ import { TalerError } from "@gnu-taler/taler-util";
import { InternalWalletState } from "../internal-wallet-state.js";
import {
LongpollResult,
- makeTransactionId,
resetOperationTimeout,
runLongpollAsync,
runOperationWithErrorReporting,
@@ -128,8 +128,10 @@ import {
import { PendingTaskType } from "../pending-types.js";
import {
constructTransactionIdentifier,
+ notifyTransition,
stopLongpolling,
} from "./transactions.js";
+import { assertUnreachable } from "../util/assertUnreachable.js";
const logger = new Logger("operations/peer-to-peer.ts");
@@ -451,19 +453,11 @@ export async function checkPeerPushDebit(
};
}
-export async function processPeerPushInitiation(
+async function processPeerPushDebitCreateReserve(
ws: InternalWalletState,
- pursePub: string,
+ peerPushInitiation: PeerPushPaymentInitiationRecord,
): Promise<OperationAttemptResult> {
- const peerPushInitiation = await ws.db
- .mktx((x) => [x.peerPushPaymentInitiations])
- .runReadOnly(async (tx) => {
- return tx.peerPushPaymentInitiations.get(pursePub);
- });
- if (!peerPushInitiation) {
- throw Error("peer push payment not found");
- }
-
+ const pursePub = peerPushInitiation.pursePub;
const purseExpiration = peerPushInitiation.purseExpiration;
const hContractTerms = peerPushInitiation.contractTermsHash;
@@ -501,22 +495,25 @@ export async function processPeerPushInitiation(
peerPushInitiation.exchangeBaseUrl,
);
- const httpResp = await ws.http.postJson(createPurseUrl.href, {
- amount: peerPushInitiation.amount,
- merge_pub: peerPushInitiation.mergePub,
- purse_sig: purseSigResp.sig,
- h_contract_terms: hContractTerms,
- purse_expiration: purseExpiration,
- deposits: depositSigsResp.deposits,
- min_age: 0,
- econtract: econtractResp.econtract,
+ const httpResp = await ws.http.fetch(createPurseUrl.href, {
+ method: "POST",
+ body: {
+ amount: peerPushInitiation.amount,
+ merge_pub: peerPushInitiation.mergePub,
+ purse_sig: purseSigResp.sig,
+ h_contract_terms: hContractTerms,
+ purse_expiration: purseExpiration,
+ deposits: depositSigsResp.deposits,
+ min_age: 0,
+ econtract: econtractResp.econtract,
+ },
});
const resp = await httpResp.json();
logger.info(`resp: ${j2s(resp)}`);
- if (httpResp.status !== 200) {
+ if (httpResp.status !== HttpStatusCode.Ok) {
throw Error("got error response from exchange");
}
@@ -527,7 +524,7 @@ export async function processPeerPushInitiation(
if (!ppi) {
return;
}
- ppi.status = PeerPushPaymentInitiationStatus.PurseCreated;
+ ppi.status = PeerPushPaymentInitiationStatus.Done;
await tx.peerPushPaymentInitiations.put(ppi);
});
@@ -537,6 +534,122 @@ export async function processPeerPushInitiation(
};
}
+async function transitionPeerPushDebitFromReadyToDone(
+ ws: InternalWalletState,
+ pursePub: string,
+): Promise<void> {
+ const transactionId = constructTransactionIdentifier({
+ tag: TransactionType.PeerPushDebit,
+ pursePub,
+ });
+ const transitionInfo = await ws.db
+ .mktx((x) => [x.peerPushPaymentInitiations])
+ .runReadWrite(async (tx) => {
+ const ppiRec = await tx.peerPushPaymentInitiations.get(pursePub);
+ if (!ppiRec) {
+ return undefined;
+ }
+ if (ppiRec.status !== PeerPushPaymentInitiationStatus.PendingReady) {
+ return undefined;
+ }
+ const oldTxState = computePeerPushDebitTransactionState(ppiRec);
+ ppiRec.status = PeerPushPaymentInitiationStatus.Done;
+ const newTxState = computePeerPushDebitTransactionState(ppiRec);
+ return {
+ oldTxState,
+ newTxState,
+ };
+ });
+ notifyTransition(ws, transactionId, transitionInfo);
+}
+
+/**
+ * Process the "pending(ready)" state of a peer-push-debit transaction.
+ */
+async function processPeerPushDebitReady(
+ ws: InternalWalletState,
+ peerPushInitiation: PeerPushPaymentInitiationRecord,
+): Promise<OperationAttemptResult> {
+ const pursePub = peerPushInitiation.pursePub;
+ const retryTag = constructTaskIdentifier({
+ tag: PendingTaskType.PeerPushDebit,
+ pursePub,
+ });
+ runLongpollAsync(ws, retryTag, async (ct) => {
+ const mergeUrl = new URL(`purses/${pursePub}/merge`);
+ mergeUrl.searchParams.set("timeout_ms", "30000");
+ const resp = await ws.http.fetch(mergeUrl.href, {
+ // timeout: getReserveRequestTimeout(withdrawalGroup),
+ cancellationToken: ct,
+ });
+ if (resp.status === HttpStatusCode.Ok) {
+ const purseStatus = await readSuccessResponseJsonOrThrow(
+ resp,
+ codecForExchangePurseStatus(),
+ );
+ if (purseStatus.deposit_timestamp) {
+ await transitionPeerPushDebitFromReadyToDone(
+ ws,
+ peerPushInitiation.pursePub,
+ );
+ return {
+ ready: true,
+ };
+ }
+ } else if (resp.status === HttpStatusCode.Gone) {
+ // FIXME: transition the reserve into the expired state
+ }
+ return {
+ ready: false,
+ };
+ });
+ logger.trace(
+ "returning early from withdrawal for long-polling in background",
+ );
+ return {
+ type: OperationAttemptResultType.Longpoll,
+ };
+}
+
+export async function processPeerPushDebit(
+ ws: InternalWalletState,
+ pursePub: string,
+): Promise<OperationAttemptResult> {
+ const peerPushInitiation = await ws.db
+ .mktx((x) => [x.peerPushPaymentInitiations])
+ .runReadOnly(async (tx) => {
+ return tx.peerPushPaymentInitiations.get(pursePub);
+ });
+ if (!peerPushInitiation) {
+ throw Error("peer push payment not found");
+ }
+
+ const retryTag = constructTaskIdentifier({
+ tag: PendingTaskType.PeerPushDebit,
+ pursePub,
+ });
+
+ // We're already running!
+ if (ws.activeLongpoll[retryTag]) {
+ logger.info("peer-push-debit task already in long-polling, returning!");
+ return {
+ type: OperationAttemptResultType.Longpoll,
+ };
+ }
+
+ switch (peerPushInitiation.status) {
+ case PeerPushPaymentInitiationStatus.PendingCreatePurse:
+ return processPeerPushDebitCreateReserve(ws, peerPushInitiation);
+ case PeerPushPaymentInitiationStatus.PendingReady:
+ return processPeerPushDebitReady(ws, peerPushInitiation);
+ }
+
+ return {
+ type: OperationAttemptResultType.Finished,
+ result: undefined,
+ };
+}
+
/**
* Initiate sending a peer-to-peer push payment.
*/
@@ -612,7 +725,7 @@ export async function initiatePeerPushPayment(
pursePriv: pursePair.priv,
pursePub: pursePair.pub,
timestampCreated: TalerProtocolTimestamp.now(),
- status: PeerPushPaymentInitiationStatus.Initiated,
+ status: PeerPushPaymentInitiationStatus.PendingCreatePurse,
contractTerms: contractTerms,
coinSel: {
coinPubs: sel.coins.map((x) => x.coinPub),
@@ -628,12 +741,12 @@ export async function initiatePeerPushPayment(
});
const taskId = constructTaskIdentifier({
- tag: PendingTaskType.PeerPushInitiation,
+ tag: PendingTaskType.PeerPushDebit,
pursePub: pursePair.pub,
});
await runOperationWithErrorReporting(ws, taskId, async () => {
- return await processPeerPushInitiation(ws, pursePair.pub);
+ return await processPeerPushDebit(ws, pursePair.pub);
});
return {
@@ -645,22 +758,24 @@ export async function initiatePeerPushPayment(
exchangeBaseUrl: coinSelRes.result.exchangeBaseUrl,
contractPriv: contractKeyPair.priv,
}),
- transactionId: makeTransactionId(
- TransactionType.PeerPushDebit,
- pursePair.pub,
- ),
+ transactionId: constructTransactionIdentifier({
+ tag: TransactionType.PeerPushDebit,
+ pursePub: pursePair.pub,
+ }),
};
}
interface ExchangePurseStatus {
balance: AmountString;
deposit_timestamp?: TalerProtocolTimestamp;
+ merge_timestamp?: TalerProtocolTimestamp;
}
export const codecForExchangePurseStatus = (): Codec<ExchangePurseStatus> =>
buildCodecForObject<ExchangePurseStatus>()
.property("balance", codecForAmountString())
.property("deposit_timestamp", codecOptional(codecForTimestamp))
+ .property("merge_timestamp", codecOptional(codecForTimestamp))
.build("ExchangePurseStatus");
export async function preparePeerPushCredit(
@@ -879,13 +994,13 @@ export async function processPeerPushCredit(
const amount = Amounts.parseOrThrow(contractTerms.amount);
if (
- peerInc.status === PeerPushPaymentIncomingStatus.KycRequired &&
+ peerInc.status === PeerPushPaymentIncomingStatus.MergeKycRequired &&
peerInc.kycInfo
) {
- const txId = makeTransactionId(
- TransactionType.PeerPushCredit,
- peerInc.peerPushPaymentIncomingId,
- );
+ const txId = constructTransactionIdentifier({
+ tag: TransactionType.PeerPushCredit,
+ peerPushPaymentIncomingId: peerInc.peerPushPaymentIncomingId,
+ });
await checkWithdrawalKycStatus(
ws,
peerInc.exchangeBaseUrl,
@@ -951,7 +1066,7 @@ export async function processPeerPushCredit(
paytoHash: kycPending.h_payto,
requirementRow: kycPending.requirement_row,
};
- peerInc.status = PeerPushPaymentIncomingStatus.KycRequired;
+ peerInc.status = PeerPushPaymentIncomingStatus.MergeKycRequired;
await tx.peerPushPaymentIncoming.put(peerInc);
});
return {
@@ -975,7 +1090,7 @@ export async function processPeerPushCredit(
},
forcedWithdrawalGroupId: peerInc.withdrawalGroupId,
exchangeBaseUrl: peerInc.exchangeBaseUrl,
- reserveStatus: WithdrawalGroupStatus.QueryingStatus,
+ reserveStatus: WithdrawalGroupStatus.PendingQueryingStatus,
reserveKeyPair: {
priv: mergeReserveInfo.reservePriv,
pub: mergeReserveInfo.reservePub,
@@ -993,9 +1108,9 @@ export async function processPeerPushCredit(
}
if (
peerInc.status === PeerPushPaymentIncomingStatus.Accepted ||
- peerInc.status === PeerPushPaymentIncomingStatus.KycRequired
+ peerInc.status === PeerPushPaymentIncomingStatus.MergeKycRequired
) {
- peerInc.status = PeerPushPaymentIncomingStatus.WithdrawalCreated;
+ peerInc.status = PeerPushPaymentIncomingStatus.Done;
}
await tx.peerPushPaymentIncoming.put(peerInc);
});
@@ -1011,7 +1126,7 @@ export async function confirmPeerPushCredit(
req: ConfirmPeerPushCreditRequest,
): Promise<AcceptPeerPushPaymentResponse> {
let peerInc: PeerPushPaymentIncomingRecord | undefined;
- let contractTerms: PeerContractTerms | undefined;
+
await ws.db
.mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming])
.runReadWrite(async (tx) => {
@@ -1021,10 +1136,6 @@ export async function confirmPeerPushCredit(
if (!peerInc) {
return;
}
- const ctRec = await tx.contractTerms.get(peerInc.contractTermsHash);
- if (ctRec) {
- contractTerms = ctRec.contractTermsRaw;
- }
if (peerInc.status === PeerPushPaymentIncomingStatus.Proposed) {
peerInc.status = PeerPushPaymentIncomingStatus.Accepted;
}
@@ -1037,21 +1148,15 @@ export async function confirmPeerPushCredit(
);
}
- checkDbInvariant(!!contractTerms);
-
- await updateExchangeFromUrl(ws, peerInc.exchangeBaseUrl);
-
- const retryTag = TaskIdentifiers.forPeerPushCredit(peerInc);
+ ws.workAvailable.trigger();
- await runOperationWithErrorReporting(ws, retryTag, () =>
- processPeerPushCredit(ws, req.peerPushPaymentIncomingId),
- );
+ const transactionId = constructTransactionIdentifier({
+ tag: TransactionType.PeerPushCredit,
+ peerPushPaymentIncomingId: req.peerPushPaymentIncomingId,
+ });
return {
- transactionId: makeTransactionId(
- TransactionType.PeerPushCredit,
- req.peerPushPaymentIncomingId,
- ),
+ transactionId,
};
}
@@ -1209,11 +1314,13 @@ export async function confirmPeerPullDebit(
},
);
+ const transactionId = constructTransactionIdentifier({
+ tag: TransactionType.PeerPullDebit,
+ peerPullPaymentIncomingId: req.peerPullPaymentIncomingId,
+ });
+
return {
- transactionId: makeTransactionId(
- TransactionType.PeerPullDebit,
- req.peerPullPaymentIncomingId,
- ),
+ transactionId,
};
}
@@ -1395,7 +1502,7 @@ export async function queryPurseForPeerPullCredit(
},
forcedWithdrawalGroupId: pullIni.withdrawalGroupId,
exchangeBaseUrl: pullIni.exchangeBaseUrl,
- reserveStatus: WithdrawalGroupStatus.QueryingStatus,
+ reserveStatus: WithdrawalGroupStatus.PendingQueryingStatus,
reserveKeyPair: {
priv: reserve.reservePriv,
pub: reserve.reservePub,
@@ -1410,8 +1517,8 @@ export async function queryPurseForPeerPullCredit(
logger.warn("peerPullPaymentInitiation not found anymore");
return;
}
- if (finPi.status === PeerPullPaymentInitiationStatus.PurseCreated) {
- finPi.status = PeerPullPaymentInitiationStatus.PurseDeposited;
+ if (finPi.status === PeerPullPaymentInitiationStatus.PendingReady) {
+ finPi.status = PeerPullPaymentInitiationStatus.DonePurseDeposited;
}
await tx.peerPullPaymentInitiations.put(finPi);
});
@@ -1434,7 +1541,7 @@ export async function processPeerPullCredit(
}
const retryTag = constructTaskIdentifier({
- tag: PendingTaskType.PeerPullInitiation,
+ tag: PendingTaskType.PeerPullCredit,
pursePub,
});
@@ -1449,7 +1556,7 @@ export async function processPeerPullCredit(
logger.trace(`processing ${retryTag}, status=${pullIni.status}`);
switch (pullIni.status) {
- case PeerPullPaymentInitiationStatus.PurseDeposited: {
+ case PeerPullPaymentInitiationStatus.DonePurseDeposited: {
// We implement this case so that the "retry" action on a peer-pull-credit transaction
// also retries the withdrawal task.
@@ -1475,7 +1582,7 @@ export async function processPeerPullCredit(
result: undefined,
};
}
- case PeerPullPaymentInitiationStatus.PurseCreated:
+ case PeerPullPaymentInitiationStatus.PendingReady:
runLongpollAsync(ws, retryTag, async (cancellationToken) =>
queryPurseForPeerPullCredit(ws, pullIni, cancellationToken),
);
@@ -1485,23 +1592,23 @@ export async function processPeerPullCredit(
return {
type: OperationAttemptResultType.Longpoll,
};
- case PeerPullPaymentInitiationStatus.KycRequired: {
+ case PeerPullPaymentInitiationStatus.PendingMergeKycRequired: {
+ const transactionId = constructTransactionIdentifier({
+ tag: TransactionType.PeerPullCredit,
+ pursePub: pullIni.pursePub,
+ });
if (pullIni.kycInfo) {
- const txId = makeTransactionId(
- TransactionType.PeerPullCredit,
- pullIni.pursePub,
- );
await checkWithdrawalKycStatus(
ws,
pullIni.exchangeBaseUrl,
- txId,
+ transactionId,
pullIni.kycInfo,
"individual",
);
}
break;
}
- case PeerPullPaymentInitiationStatus.Initial:
+ case PeerPullPaymentInitiationStatus.PendingCreatePurse:
break;
default:
throw Error(`unknown PeerPullPaymentInitiationStatus ${pullIni.status}`);
@@ -1590,7 +1697,8 @@ export async function processPeerPullCredit(
paytoHash: kycPending.h_payto,
requirementRow: kycPending.requirement_row,
};
- peerIni.status = PeerPullPaymentInitiationStatus.KycRequired;
+ peerIni.status =
+ PeerPullPaymentInitiationStatus.PendingMergeKycRequired;
await tx.peerPullPaymentInitiations.put(peerIni);
});
return {
@@ -1610,7 +1718,7 @@ export async function processPeerPullCredit(
if (!pi2) {
return;
}
- pi2.status = PeerPullPaymentInitiationStatus.PurseCreated;
+ pi2.status = PeerPullPaymentInitiationStatus.PendingReady;
await tx.peerPullPaymentInitiations.put(pi2);
});
@@ -1776,7 +1884,7 @@ export async function initiatePeerPullPayment(
pursePub: pursePair.pub,
mergePriv: mergePair.priv,
mergePub: mergePair.pub,
- status: PeerPullPaymentInitiationStatus.Initial,
+ status: PeerPullPaymentInitiationStatus.PendingCreatePurse,
contractTerms: contractTerms,
mergeTimestamp,
mergeReserveRowId: mergeReserveRowId,
@@ -1796,7 +1904,7 @@ export async function initiatePeerPullPayment(
// check this asynchronously from the transaction status?
const taskId = constructTaskIdentifier({
- tag: PendingTaskType.PeerPullInitiation,
+ tag: PendingTaskType.PeerPullCredit,
pursePub: pursePair.pub,
});
@@ -1804,14 +1912,408 @@ export async function initiatePeerPullPayment(
return processPeerPullCredit(ws, pursePair.pub);
});
+ const transactionId = constructTransactionIdentifier({
+ tag: TransactionType.PeerPullCredit,
+ pursePub: pursePair.pub,
+ });
+
return {
talerUri: constructPayPullUri({
exchangeBaseUrl: exchangeBaseUrl,
contractPriv: contractKeyPair.priv,
}),
- transactionId: makeTransactionId(
- TransactionType.PeerPullCredit,
- pursePair.pub,
- ),
+ transactionId,
};
}
+
+export function computePeerPushDebitTransactionState(
+ ppiRecord: PeerPushPaymentInitiationRecord,
+): TransactionState {
+ switch (ppiRecord.status) {
+ case PeerPushPaymentInitiationStatus.PendingCreatePurse:
+ return {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.CreatePurse,
+ };
+ case PeerPushPaymentInitiationStatus.PendingReady:
+ return {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Ready,
+ };
+ case PeerPushPaymentInitiationStatus.Aborted:
+ return {
+ major: TransactionMajorState.Aborted,
+ };
+ case PeerPushPaymentInitiationStatus.AbortingDeletePurse:
+ return {
+ major: TransactionMajorState.Aborting,
+ minor: TransactionMinorState.DeletePurse,
+ };
+ case PeerPushPaymentInitiationStatus.AbortingRefresh:
+ return {
+ major: TransactionMajorState.Aborting,
+ minor: TransactionMinorState.Refresh,
+ };
+ case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse:
+ return {
+ major: TransactionMajorState.SuspendedAborting,
+ minor: TransactionMinorState.DeletePurse,
+ };
+ case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh:
+ return {
+ major: TransactionMajorState.SuspendedAborting,
+ minor: TransactionMinorState.Refresh,
+ };
+ case PeerPushPaymentInitiationStatus.SuspendedCreatePurse:
+ return {
+ major: TransactionMajorState.Suspended,
+ minor: TransactionMinorState.CreatePurse,
+ };
+ case PeerPushPaymentInitiationStatus.SuspendedReady:
+ return {
+ major: TransactionMajorState.Suspended,
+ minor: TransactionMinorState.Ready,
+ };
+ case PeerPushPaymentInitiationStatus.Done:
+ return {
+ major: TransactionMajorState.Done,
+ };
+ }
+}
+
+export async function abortPeerPushDebitTransaction(
+ ws: InternalWalletState,
+ pursePub: string,
+) {
+ const taskId = constructTaskIdentifier({
+ tag: PendingTaskType.PeerPushDebit,
+ pursePub,
+ });
+ const transactionId = constructTransactionIdentifier({
+ tag: TransactionType.PeerPushDebit,
+ pursePub,
+ });
+ stopLongpolling(ws, taskId);
+ const transitionInfo = await ws.db
+ .mktx((x) => [x.peerPushPaymentInitiations])
+ .runReadWrite(async (tx) => {
+ const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub);
+ if (!pushDebitRec) {
+ logger.warn(`peer push debit ${pursePub} not found`);
+ return;
+ }
+ let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined;
+ switch (pushDebitRec.status) {
+ case PeerPushPaymentInitiationStatus.PendingReady:
+ case PeerPushPaymentInitiationStatus.SuspendedReady:
+ newStatus = PeerPushPaymentInitiationStatus.AbortingDeletePurse;
+ break;
+ case PeerPushPaymentInitiationStatus.SuspendedCreatePurse:
+ case PeerPushPaymentInitiationStatus.PendingCreatePurse:
+ // Network request might already be in-flight!
+ newStatus = PeerPushPaymentInitiationStatus.AbortingDeletePurse;
+ break;
+ case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh:
+ case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse:
+ case PeerPushPaymentInitiationStatus.AbortingRefresh:
+ case PeerPushPaymentInitiationStatus.Done:
+ case PeerPushPaymentInitiationStatus.AbortingDeletePurse:
+ case PeerPushPaymentInitiationStatus.Aborted:
+ // Do nothing
+ break;
+ default:
+ assertUnreachable(pushDebitRec.status);
+ }
+ if (newStatus != null) {
+ const oldTxState = computePeerPushDebitTransactionState(pushDebitRec);
+ pushDebitRec.status = newStatus;
+ const newTxState = computePeerPushDebitTransactionState(pushDebitRec);
+ await tx.peerPushPaymentInitiations.put(pushDebitRec);
+ return {
+ oldTxState,
+ newTxState,
+ };
+ }
+ return undefined;
+ });
+ notifyTransition(ws, transactionId, transitionInfo);
+}
+
+export async function cancelAbortingPeerPushDebitTransaction(
+ ws: InternalWalletState,
+ pursePub: string,
+) {
+ const taskId = constructTaskIdentifier({
+ tag: PendingTaskType.PeerPushDebit,
+ pursePub,
+ });
+ const transactionId = constructTransactionIdentifier({
+ tag: TransactionType.PeerPushDebit,
+ pursePub,
+ });
+ stopLongpolling(ws, taskId);
+ const transitionInfo = await ws.db
+ .mktx((x) => [x.peerPushPaymentInitiations])
+ .runReadWrite(async (tx) => {
+ const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub);
+ if (!pushDebitRec) {
+ logger.warn(`peer push debit ${pursePub} not found`);
+ return;
+ }
+ let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined;
+ switch (pushDebitRec.status) {
+ case PeerPushPaymentInitiationStatus.AbortingRefresh:
+ case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh:
+ // FIXME: We also need to abort the refresh group!
+ newStatus = PeerPushPaymentInitiationStatus.Aborted;
+ break;
+ case PeerPushPaymentInitiationStatus.AbortingDeletePurse:
+ case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse:
+ newStatus = PeerPushPaymentInitiationStatus.Aborted;
+ break;
+ case PeerPushPaymentInitiationStatus.PendingReady:
+ case PeerPushPaymentInitiationStatus.SuspendedReady:
+ case PeerPushPaymentInitiationStatus.SuspendedCreatePurse:
+ case PeerPushPaymentInitiationStatus.PendingCreatePurse:
+ case PeerPushPaymentInitiationStatus.Done:
+ case PeerPushPaymentInitiationStatus.Aborted:
+ // Do nothing
+ break;
+ default:
+ assertUnreachable(pushDebitRec.status);
+ }
+ if (newStatus != null) {
+ const oldTxState = computePeerPushDebitTransactionState(pushDebitRec);
+ pushDebitRec.status = newStatus;
+ const newTxState = computePeerPushDebitTransactionState(pushDebitRec);
+ await tx.peerPushPaymentInitiations.put(pushDebitRec);
+ return {
+ oldTxState,
+ newTxState,
+ };
+ }
+ return undefined;
+ });
+ notifyTransition(ws, transactionId, transitionInfo);
+}
+
+export async function suspendPeerPushDebitTransaction(
+ ws: InternalWalletState,
+ pursePub: string,
+) {
+ const taskId = constructTaskIdentifier({
+ tag: PendingTaskType.PeerPushDebit,
+ pursePub,
+ });
+ const transactionId = constructTransactionIdentifier({
+ tag: TransactionType.PeerPushDebit,
+ pursePub,
+ });
+ stopLongpolling(ws, taskId);
+ const transitionInfo = await ws.db
+ .mktx((x) => [x.peerPushPaymentInitiations])
+ .runReadWrite(async (tx) => {
+ const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub);
+ if (!pushDebitRec) {
+ logger.warn(`peer push debit ${pursePub} not found`);
+ return;
+ }
+ let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined;
+ switch (pushDebitRec.status) {
+ case PeerPushPaymentInitiationStatus.PendingCreatePurse:
+ newStatus = PeerPushPaymentInitiationStatus.SuspendedCreatePurse;
+ break;
+ case PeerPushPaymentInitiationStatus.AbortingRefresh:
+ newStatus = PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh;
+ break;
+ case PeerPushPaymentInitiationStatus.AbortingDeletePurse:
+ newStatus =
+ PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse;
+ break;
+ case PeerPushPaymentInitiationStatus.PendingReady:
+ newStatus = PeerPushPaymentInitiationStatus.SuspendedReady;
+ break;
+ case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse:
+ case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh:
+ case PeerPushPaymentInitiationStatus.SuspendedReady:
+ case PeerPushPaymentInitiationStatus.SuspendedCreatePurse:
+ case PeerPushPaymentInitiationStatus.Done:
+ case PeerPushPaymentInitiationStatus.Aborted:
+ // Do nothing
+ break;
+ default:
+ assertUnreachable(pushDebitRec.status);
+ }
+ if (newStatus != null) {
+ const oldTxState = computePeerPushDebitTransactionState(pushDebitRec);
+ pushDebitRec.status = newStatus;
+ const newTxState = computePeerPushDebitTransactionState(pushDebitRec);
+ await tx.peerPushPaymentInitiations.put(pushDebitRec);
+ return {
+ oldTxState,
+ newTxState,
+ };
+ }
+ return undefined;
+ });
+ notifyTransition(ws, transactionId, transitionInfo);
+}
+
+export async function resumePeerPushDebitTransaction(
+ ws: InternalWalletState,
+ pursePub: string,
+) {
+ const taskId = constructTaskIdentifier({
+ tag: PendingTaskType.PeerPushDebit,
+ pursePub,
+ });
+ const transactionId = constructTransactionIdentifier({
+ tag: TransactionType.PeerPushDebit,
+ pursePub,
+ });
+ stopLongpolling(ws, taskId);
+ const transitionInfo = await ws.db
+ .mktx((x) => [x.peerPushPaymentInitiations])
+ .runReadWrite(async (tx) => {
+ const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub);
+ if (!pushDebitRec) {
+ logger.warn(`peer push debit ${pursePub} not found`);
+ return;
+ }
+ let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined;
+ switch (pushDebitRec.status) {
+ case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse:
+ newStatus = PeerPushPaymentInitiationStatus.AbortingDeletePurse;
+ break;
+ case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh:
+ newStatus = PeerPushPaymentInitiationStatus.AbortingRefresh;
+ break;
+ case PeerPushPaymentInitiationStatus.SuspendedReady:
+ newStatus = PeerPushPaymentInitiationStatus.PendingReady;
+ break;
+ case PeerPushPaymentInitiationStatus.SuspendedCreatePurse:
+ newStatus = PeerPushPaymentInitiationStatus.PendingCreatePurse;
+ break;
+ case PeerPushPaymentInitiationStatus.PendingCreatePurse:
+ case PeerPushPaymentInitiationStatus.AbortingRefresh:
+ case PeerPushPaymentInitiationStatus.AbortingDeletePurse:
+ case PeerPushPaymentInitiationStatus.PendingReady:
+ case PeerPushPaymentInitiationStatus.Done:
+ case PeerPushPaymentInitiationStatus.Aborted:
+ // Do nothing
+ break;
+ default:
+ assertUnreachable(pushDebitRec.status);
+ }
+ if (newStatus != null) {
+ const oldTxState = computePeerPushDebitTransactionState(pushDebitRec);
+ pushDebitRec.status = newStatus;
+ const newTxState = computePeerPushDebitTransactionState(pushDebitRec);
+ await tx.peerPushPaymentInitiations.put(pushDebitRec);
+ return {
+ oldTxState,
+ newTxState,
+ };
+ }
+ return undefined;
+ });
+ notifyTransition(ws, transactionId, transitionInfo);
+}
+
+export function computePeerPushCreditTransactionState(
+ pushCreditRecord: PeerPushPaymentIncomingRecord,
+): TransactionState {
+ switch (pushCreditRecord.status) {
+ case PeerPushPaymentIncomingStatus.Proposed:
+ return {
+ major: TransactionMajorState.Dialog,
+ minor: TransactionMinorState.Proposed,
+ };
+ case PeerPushPaymentIncomingStatus.Accepted:
+ return {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Merge,
+ };
+ case PeerPushPaymentIncomingStatus.Done:
+ return {
+ major: TransactionMajorState.Done,
+ };
+ case PeerPushPaymentIncomingStatus.MergeKycRequired:
+ return {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.KycRequired,
+ };
+ case PeerPushPaymentIncomingStatus.Withdrawing:
+ return {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Withdraw,
+ };
+ }
+}
+
+export function computePeerPullCreditTransactionState(
+ pullCreditRecord: PeerPullPaymentInitiationRecord,
+): TransactionState {
+ switch (pullCreditRecord.status) {
+ case PeerPullPaymentInitiationStatus.PendingCreatePurse:
+ return {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.CreatePurse,
+ };
+ case PeerPullPaymentInitiationStatus.PendingMergeKycRequired:
+ return {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.MergeKycRequired,
+ };
+ case PeerPullPaymentInitiationStatus.PendingReady:
+ return {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Ready,
+ };
+ case PeerPullPaymentInitiationStatus.DonePurseDeposited:
+ return {
+ major: TransactionMajorState.Done,
+ };
+ case PeerPullPaymentInitiationStatus.PendingWithdrawing:
+ return {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Withdraw,
+ };
+ case PeerPullPaymentInitiationStatus.SuspendedCreatePurse:
+ return {
+ major: TransactionMajorState.Suspended,
+ minor: TransactionMinorState.CreatePurse,
+ };
+ case PeerPullPaymentInitiationStatus.SuspendedReady:
+ return {
+ major: TransactionMajorState.Suspended,
+ minor: TransactionMinorState.Ready,
+ };
+ case PeerPullPaymentInitiationStatus.SuspendedWithdrawing:
+ return {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Withdraw,
+ };
+ }
+}
+
+export function computePeerPullDebitTransactionState(
+ pullDebitRecord: PeerPullPaymentIncomingRecord,
+): TransactionState {
+ switch (pullDebitRecord.status) {
+ case PeerPullPaymentIncomingStatus.Proposed:
+ return {
+ major: TransactionMajorState.Dialog,
+ minor: TransactionMinorState.Proposed,
+ };
+ case PeerPullPaymentIncomingStatus.Accepted:
+ return {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Deposit,
+ };
+ case PeerPullPaymentIncomingStatus.Paid:
+ return {
+ major: TransactionMajorState.Done,
+ };
+ }
+}
diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts
index 5e14721f8..084f807f2 100644
--- a/packages/taler-wallet-core/src/operations/pending.ts
+++ b/packages/taler-wallet-core/src/operations/pending.ts
@@ -364,14 +364,14 @@ async function gatherPeerPullInitiationPending(
resp: PendingOperationsResponse,
): Promise<void> {
await tx.peerPullPaymentInitiations.iter().forEachAsync(async (pi) => {
- if (pi.status === PeerPullPaymentInitiationStatus.PurseDeposited) {
+ if (pi.status === PeerPullPaymentInitiationStatus.DonePurseDeposited) {
return;
}
const opId = TaskIdentifiers.forPeerPullPaymentInitiation(pi);
const retryRecord = await tx.operationRetries.get(opId);
const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now();
resp.pendingOperations.push({
- type: PendingTaskType.PeerPullInitiation,
+ type: PendingTaskType.PeerPullCredit,
...getPendingCommon(ws, opId, timestampDue),
givesLifeness: true,
retryInfo: retryRecord?.retryInfo,
@@ -421,14 +421,14 @@ async function gatherPeerPushInitiationPending(
resp: PendingOperationsResponse,
): Promise<void> {
await tx.peerPushPaymentInitiations.iter().forEachAsync(async (pi) => {
- if (pi.status === PeerPushPaymentInitiationStatus.PurseCreated) {
+ if (pi.status === PeerPushPaymentInitiationStatus.Done) {
return;
}
const opId = TaskIdentifiers.forPeerPushPaymentInitiation(pi);
const retryRecord = await tx.operationRetries.get(opId);
const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now();
resp.pendingOperations.push({
- type: PendingTaskType.PeerPushInitiation,
+ type: PendingTaskType.PeerPushDebit,
...getPendingCommon(ws, opId, timestampDue),
givesLifeness: true,
retryInfo: retryRecord?.retryInfo,
@@ -450,7 +450,7 @@ async function gatherPeerPushCreditPending(
switch (pi.status) {
case PeerPushPaymentIncomingStatus.Proposed:
return;
- case PeerPushPaymentIncomingStatus.WithdrawalCreated:
+ case PeerPushPaymentIncomingStatus.Done:
return;
}
const opId = TaskIdentifiers.forPeerPushCredit(pi);
diff --git a/packages/taler-wallet-core/src/operations/recoup.ts b/packages/taler-wallet-core/src/operations/recoup.ts
index 3b423474b..982f3cf8c 100644
--- a/packages/taler-wallet-core/src/operations/recoup.ts
+++ b/packages/taler-wallet-core/src/operations/recoup.ts
@@ -400,7 +400,7 @@ export async function processRecoupGroupHandler(
await internalCreateWithdrawalGroup(ws, {
amount: Amounts.parseOrThrow(result.balance),
exchangeBaseUrl: recoupGroup.exchangeBaseUrl,
- reserveStatus: WithdrawalGroupStatus.QueryingStatus,
+ reserveStatus: WithdrawalGroupStatus.PendingQueryingStatus,
reserveKeyPair: {
pub: reservePub,
priv: reservePrivMap[reservePub],
diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts
index 748c929c2..fda9a886a 100644
--- a/packages/taler-wallet-core/src/operations/refresh.ts
+++ b/packages/taler-wallet-core/src/operations/refresh.ts
@@ -1125,7 +1125,7 @@ export async function autoRefresh(
return OperationAttemptResult.finishedEmpty();
}
-export function computeRefreshTransactionStatus(
+export function computeRefreshTransactionState(
rg: RefreshGroupRecord,
): TransactionState {
switch (rg.operationStatus) {
@@ -1170,7 +1170,7 @@ export async function suspendRefreshGroup(
);
return undefined;
}
- const oldState = computeRefreshTransactionStatus(dg);
+ const oldState = computeRefreshTransactionState(dg);
switch (dg.operationStatus) {
case RefreshOperationStatus.Finished:
return undefined;
@@ -1179,7 +1179,7 @@ export async function suspendRefreshGroup(
await tx.refreshGroups.put(dg);
return {
oldTxState: oldState,
- newTxState: computeRefreshTransactionStatus(dg),
+ newTxState: computeRefreshTransactionState(dg),
};
}
case RefreshOperationStatus.Suspended:
@@ -1215,7 +1215,7 @@ export async function resumeRefreshGroup(
);
return;
}
- const oldState = computeRefreshTransactionStatus(dg);
+ const oldState = computeRefreshTransactionState(dg);
switch (dg.operationStatus) {
case RefreshOperationStatus.Finished:
return;
@@ -1227,12 +1227,12 @@ export async function resumeRefreshGroup(
await tx.refreshGroups.put(dg);
return {
oldTxState: oldState,
- newTxState: computeRefreshTransactionStatus(dg),
+ newTxState: computeRefreshTransactionState(dg),
};
}
return undefined;
});
- ws.latch.trigger();
+ ws.workAvailable.trigger();
if (res) {
ws.notify({
type: NotificationType.TransactionStateTransition,
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts
index c122bb651..02f11d82d 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -87,14 +87,14 @@ import {
} from "./deposits.js";
import { getExchangeDetails } from "./exchanges.js";
import {
- abortPay,
+ abortPayMerchant,
computePayMerchantTransactionState,
expectProposalDownload,
extractContractData,
processPurchasePay,
} from "./pay-merchant.js";
-import { processPeerPullCredit } from "./pay-peer.js";
-import { 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,
@@ -445,7 +445,7 @@ function buildTransactionForPushPaymentDebit(
): Transaction {
return {
type: TransactionType.PeerPushDebit,
- txState: mkTxStateUnknown(),
+ txState: computePeerPushDebitTransactionState(pi),
amountEffective: pi.totalCost,
amountRaw: pi.amount,
exchangeBaseUrl: pi.exchangeBaseUrl,
@@ -455,10 +455,10 @@ function buildTransactionForPushPaymentDebit(
},
frozen: false,
extendedStatus:
- pi.status != PeerPushPaymentInitiationStatus.PurseCreated
+ pi.status != PeerPushPaymentInitiationStatus.Done
? ExtendedStatus.Pending
: ExtendedStatus.Done,
- pending: pi.status != PeerPushPaymentInitiationStatus.PurseCreated,
+ pending: pi.status != PeerPushPaymentInitiationStatus.Done,
timestamp: pi.timestampCreated,
talerUri: constructPayPushUri({
exchangeBaseUrl: pi.exchangeBaseUrl,
@@ -478,7 +478,7 @@ function buildTransactionForPullPaymentDebit(
): Transaction {
return {
type: TransactionType.PeerPullDebit,
- txState: mkTxStateUnknown(),
+ txState: computePeerPullDebitTransactionState(pi),
amountEffective: pi.coinSel?.totalCost
? pi.coinSel?.totalCost
: Amounts.stringify(pi.contractTerms.amount),
@@ -528,7 +528,7 @@ function buildTransactionForPeerPullCredit(
});
return {
type: TransactionType.PeerPullCredit,
- txState: mkTxStateUnknown(),
+ txState: computePeerPullCreditTransactionState(pullCredit),
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
amountRaw: Amounts.stringify(wsr.instructedAmount),
exchangeBaseUrl: wsr.exchangeBaseUrl,
@@ -563,7 +563,7 @@ function buildTransactionForPeerPullCredit(
return {
type: TransactionType.PeerPullCredit,
- txState: mkTxStateUnknown(),
+ txState: computePeerPullCreditTransactionState(pullCredit),
amountEffective: Amounts.stringify(pullCredit.estimatedAmountEffective),
amountRaw: Amounts.stringify(peerContractTerms.amount),
exchangeBaseUrl: pullCredit.exchangeBaseUrl,
@@ -602,7 +602,7 @@ function buildTransactionForPeerPushCredit(
return {
type: TransactionType.PeerPushCredit,
- txState: mkTxStateUnknown(),
+ txState: computePeerPushCreditTransactionState(pushInc),
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
amountRaw: Amounts.stringify(wsr.instructedAmount),
exchangeBaseUrl: wsr.exchangeBaseUrl,
@@ -626,7 +626,7 @@ function buildTransactionForPeerPushCredit(
return {
type: TransactionType.PeerPushCredit,
- txState: mkTxStateUnknown(),
+ txState: computePeerPushCreditTransactionState(pushInc),
// FIXME: This is wrong, needs to consider fees!
amountEffective: Amounts.stringify(peerContractTerms.amount),
amountRaw: Amounts.stringify(peerContractTerms.amount),
@@ -666,7 +666,7 @@ function buildTransactionForBankIntegratedWithdraw(
bankConfirmationUrl: wgRecord.wgInfo.bankInfo.confirmUrl,
reserveIsReady:
wgRecord.status === WithdrawalGroupStatus.Finished ||
- wgRecord.status === WithdrawalGroupStatus.Ready,
+ wgRecord.status === WithdrawalGroupStatus.PendingReady,
},
exchangeBaseUrl: wgRecord.exchangeBaseUrl,
extendedStatus: wgRecord.timestampFinish
@@ -713,7 +713,7 @@ function buildTransactionForManualWithdraw(
exchangePaytoUris,
reserveIsReady:
withdrawalGroup.status === WithdrawalGroupStatus.Finished ||
- withdrawalGroup.status === WithdrawalGroupStatus.Ready,
+ withdrawalGroup.status === WithdrawalGroupStatus.PendingReady,
},
exchangeBaseUrl: withdrawalGroup.exchangeBaseUrl,
extendedStatus: withdrawalGroup.timestampFinish
@@ -753,7 +753,7 @@ function buildTransactionForRefresh(
).amount;
return {
type: TransactionType.Refresh,
- txState: mkTxStateUnknown(),
+ txState: computeRefreshTransactionState(refreshGroupRecord),
refreshReason: refreshGroupRecord.reason,
amountEffective: Amounts.stringify(
Amounts.zeroOfCurrency(refreshGroupRecord.currency),
@@ -1538,7 +1538,7 @@ export async function retryTransaction(
switch (parsedTx.tag) {
case TransactionType.PeerPullCredit: {
const taskId = constructTaskIdentifier({
- tag: PendingTaskType.PeerPullInitiation,
+ tag: PendingTaskType.PeerPullCredit,
pursePub: parsedTx.pursePub,
});
await resetOperationTimeout(ws, taskId);
@@ -1866,7 +1866,7 @@ export async function abortTransaction(
switch (txId.tag) {
case TransactionType.Payment: {
- await abortPay(ws, txId.proposalId);
+ await abortPayMerchant(ws, txId.proposalId);
break;
}
case TransactionType.Withdrawal: {
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts
index d1816de03..d0c4d453f 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -135,6 +135,7 @@ import {
notifyTransition,
stopLongpolling,
} from "./transactions.js";
+import { assertUnreachable } from "../util/assertUnreachable.js";
/**
* Logger for this file.
@@ -160,25 +161,25 @@ export async function suspendWithdrawalTransaction(
}
let newStatus: WithdrawalGroupStatus | undefined = undefined;
switch (wg.status) {
- case WithdrawalGroupStatus.Ready:
+ case WithdrawalGroupStatus.PendingReady:
newStatus = WithdrawalGroupStatus.SuspendedReady;
break;
case WithdrawalGroupStatus.AbortingBank:
newStatus = WithdrawalGroupStatus.SuspendedAbortingBank;
break;
- case WithdrawalGroupStatus.WaitConfirmBank:
+ case WithdrawalGroupStatus.PendingWaitConfirmBank:
newStatus = WithdrawalGroupStatus.SuspendedWaitConfirmBank;
break;
- case WithdrawalGroupStatus.RegisteringBank:
+ case WithdrawalGroupStatus.PendingRegisteringBank:
newStatus = WithdrawalGroupStatus.SuspendedRegisteringBank;
break;
- case WithdrawalGroupStatus.QueryingStatus:
- newStatus = WithdrawalGroupStatus.QueryingStatus;
+ case WithdrawalGroupStatus.PendingQueryingStatus:
+ newStatus = WithdrawalGroupStatus.SuspendedQueryingStatus;
break;
- case WithdrawalGroupStatus.Kyc:
+ case WithdrawalGroupStatus.PendingKyc:
newStatus = WithdrawalGroupStatus.SuspendedKyc;
break;
- case WithdrawalGroupStatus.Aml:
+ case WithdrawalGroupStatus.PendingAml:
newStatus = WithdrawalGroupStatus.SuspendedAml;
break;
default:
@@ -221,25 +222,25 @@ export async function resumeWithdrawalTransaction(
let newStatus: WithdrawalGroupStatus | undefined = undefined;
switch (wg.status) {
case WithdrawalGroupStatus.SuspendedReady:
- newStatus = WithdrawalGroupStatus.Ready;
+ newStatus = WithdrawalGroupStatus.PendingReady;
break;
case WithdrawalGroupStatus.SuspendedAbortingBank:
newStatus = WithdrawalGroupStatus.AbortingBank;
break;
case WithdrawalGroupStatus.SuspendedWaitConfirmBank:
- newStatus = WithdrawalGroupStatus.WaitConfirmBank;
+ newStatus = WithdrawalGroupStatus.PendingWaitConfirmBank;
break;
case WithdrawalGroupStatus.SuspendedQueryingStatus:
- newStatus = WithdrawalGroupStatus.QueryingStatus;
+ newStatus = WithdrawalGroupStatus.PendingQueryingStatus;
break;
case WithdrawalGroupStatus.SuspendedRegisteringBank:
- newStatus = WithdrawalGroupStatus.RegisteringBank;
+ newStatus = WithdrawalGroupStatus.PendingRegisteringBank;
break;
case WithdrawalGroupStatus.SuspendedAml:
- newStatus = WithdrawalGroupStatus.Aml;
+ newStatus = WithdrawalGroupStatus.PendingAml;
break;
case WithdrawalGroupStatus.SuspendedKyc:
- newStatus = WithdrawalGroupStatus.Kyc;
+ newStatus = WithdrawalGroupStatus.PendingKyc;
break;
default:
logger.warn(
@@ -289,21 +290,21 @@ export async function abortWithdrawalTransaction(
}
let newStatus: WithdrawalGroupStatus | undefined = undefined;
switch (wg.status) {
- case WithdrawalGroupStatus.WaitConfirmBank:
- case WithdrawalGroupStatus.RegisteringBank:
+ case WithdrawalGroupStatus.PendingWaitConfirmBank:
+ case WithdrawalGroupStatus.PendingRegisteringBank:
case WithdrawalGroupStatus.AbortingBank:
newStatus = WithdrawalGroupStatus.AbortingBank;
break;
- case WithdrawalGroupStatus.Aml:
+ case WithdrawalGroupStatus.PendingAml:
newStatus = WithdrawalGroupStatus.SuspendedAml;
break;
- case WithdrawalGroupStatus.Kyc:
+ case WithdrawalGroupStatus.PendingKyc:
newStatus = WithdrawalGroupStatus.SuspendedKyc;
break;
- case WithdrawalGroupStatus.QueryingStatus:
+ case WithdrawalGroupStatus.PendingQueryingStatus:
newStatus = WithdrawalGroupStatus.SuspendedQueryingStatus;
break;
- case WithdrawalGroupStatus.Ready:
+ case WithdrawalGroupStatus.PendingReady:
newStatus = WithdrawalGroupStatus.SuspendedReady;
break;
case WithdrawalGroupStatus.SuspendedAbortingBank:
@@ -316,9 +317,13 @@ export async function abortWithdrawalTransaction(
case WithdrawalGroupStatus.SuspendedRegisteringBank:
case WithdrawalGroupStatus.SuspendedWaitConfirmBank:
case WithdrawalGroupStatus.Finished:
- case WithdrawalGroupStatus.BankAborted:
+ case WithdrawalGroupStatus.FailedBankAborted:
+ case WithdrawalGroupStatus.AbortedExchange:
+ case WithdrawalGroupStatus.FailedAbortingBank:
// Not allowed
break;
+ default:
+ assertUnreachable(wg.status);
}
if (newStatus != null) {
const oldTxState = computeWithdrawalTransactionStatus(wg);
@@ -385,7 +390,7 @@ export function computeWithdrawalTransactionStatus(
wgRecord: WithdrawalGroupRecord,
): TransactionState {
switch (wgRecord.status) {
- case WithdrawalGroupStatus.BankAborted:
+ case WithdrawalGroupStatus.FailedBankAborted:
return {
major: TransactionMajorState.Aborted,
};
@@ -393,22 +398,22 @@ export function computeWithdrawalTransactionStatus(
return {
major: TransactionMajorState.Done,
};
- case WithdrawalGroupStatus.RegisteringBank:
+ case WithdrawalGroupStatus.PendingRegisteringBank:
return {
major: TransactionMajorState.Pending,
minor: TransactionMinorState.BankRegisterReserve,
};
- case WithdrawalGroupStatus.Ready:
+ case WithdrawalGroupStatus.PendingReady:
return {
major: TransactionMajorState.Pending,
minor: TransactionMinorState.WithdrawCoins,
};
- case WithdrawalGroupStatus.QueryingStatus:
+ case WithdrawalGroupStatus.PendingQueryingStatus:
return {
major: TransactionMajorState.Pending,
minor: TransactionMinorState.ExchangeWaitReserve,
};
- case WithdrawalGroupStatus.WaitConfirmBank:
+ case WithdrawalGroupStatus.PendingWaitConfirmBank:
return {
major: TransactionMajorState.Pending,
minor: TransactionMinorState.BankConfirmTransfer,
@@ -444,13 +449,13 @@ export function computeWithdrawalTransactionStatus(
minor: TransactionMinorState.WithdrawCoins,
};
}
- case WithdrawalGroupStatus.Aml: {
+ case WithdrawalGroupStatus.PendingAml: {
return {
major: TransactionMajorState.Pending,
minor: TransactionMinorState.AmlRequired,
};
}
- case WithdrawalGroupStatus.Kyc: {
+ case WithdrawalGroupStatus.PendingKyc: {
return {
major: TransactionMajorState.Pending,
minor: TransactionMinorState.KycRequired,
@@ -473,6 +478,11 @@ export function computeWithdrawalTransactionStatus(
major: TransactionMajorState.Failed,
minor: TransactionMinorState.AbortingBank,
};
+ case WithdrawalGroupStatus.AbortedExchange:
+ return {
+ major: TransactionMajorState.Aborted,
+ minor: TransactionMinorState.Exchange,
+ }
}
}
@@ -1122,7 +1132,7 @@ async function queryReserve(
withdrawalGroupId,
});
checkDbInvariant(!!withdrawalGroup);
- if (withdrawalGroup.status !== WithdrawalGroupStatus.QueryingStatus) {
+ if (withdrawalGroup.status !== WithdrawalGroupStatus.PendingQueryingStatus) {
return { ready: true };
}
const reservePub = withdrawalGroup.reservePub;
@@ -1135,7 +1145,7 @@ async function queryReserve(
logger.info(`querying reserve status via ${reserveUrl.href}`);
- const resp = await ws.http.get(reserveUrl.href, {
+ const resp = await ws.http.fetch(reserveUrl.href, {
timeout: getReserveRequestTimeout(withdrawalGroup),
cancellationToken,
});
@@ -1177,7 +1187,7 @@ async function queryReserve(
return undefined;
}
const txStateOld = computeWithdrawalTransactionStatus(wg);
- wg.status = WithdrawalGroupStatus.Ready;
+ wg.status = WithdrawalGroupStatus.PendingReady;
const txStateNew = computeWithdrawalTransactionStatus(wg);
wg.reserveBalanceAmount = Amounts.stringify(result.response.balance);
await tx.withdrawalGroups.put(wg);
@@ -1250,12 +1260,12 @@ export async function processWithdrawalGroup(
}
switch (withdrawalGroup.status) {
- case WithdrawalGroupStatus.RegisteringBank:
+ case WithdrawalGroupStatus.PendingRegisteringBank:
await processReserveBankStatus(ws, withdrawalGroupId);
return await processWithdrawalGroup(ws, withdrawalGroupId, {
forceNow: true,
});
- case WithdrawalGroupStatus.QueryingStatus: {
+ case WithdrawalGroupStatus.PendingQueryingStatus: {
runLongpollAsync(ws, retryTag, (ct) => {
return queryReserve(ws, withdrawalGroupId, ct);
});
@@ -1266,7 +1276,7 @@ export async function processWithdrawalGroup(
type: OperationAttemptResultType.Longpoll,
};
}
- case WithdrawalGroupStatus.WaitConfirmBank: {
+ case WithdrawalGroupStatus.PendingWaitConfirmBank: {
const res = await processReserveBankStatus(ws, withdrawalGroupId);
switch (res.status) {
case BankStatusResultCode.Aborted:
@@ -1284,7 +1294,7 @@ export async function processWithdrawalGroup(
}
break;
}
- case WithdrawalGroupStatus.BankAborted: {
+ case WithdrawalGroupStatus.FailedBankAborted: {
// FIXME
return {
type: OperationAttemptResultType.Pending,
@@ -1294,7 +1304,7 @@ export async function processWithdrawalGroup(
case WithdrawalGroupStatus.Finished:
// We can try to withdraw, nothing needs to be done with the reserve.
break;
- case WithdrawalGroupStatus.Ready:
+ case WithdrawalGroupStatus.PendingReady:
// Continue with the actual withdrawal!
break;
default:
@@ -1847,8 +1857,8 @@ async function registerReserveWithBank(
withdrawalGroupId,
});
switch (withdrawalGroup?.status) {
- case WithdrawalGroupStatus.WaitConfirmBank:
- case WithdrawalGroupStatus.RegisteringBank:
+ case WithdrawalGroupStatus.PendingWaitConfirmBank:
+ case WithdrawalGroupStatus.PendingRegisteringBank:
break;
default:
return;
@@ -1885,8 +1895,8 @@ async function registerReserveWithBank(
return undefined;
}
switch (r.status) {
- case WithdrawalGroupStatus.RegisteringBank:
- case WithdrawalGroupStatus.WaitConfirmBank:
+ case WithdrawalGroupStatus.PendingRegisteringBank:
+ case WithdrawalGroupStatus.PendingWaitConfirmBank:
break;
default:
return;
@@ -1898,7 +1908,7 @@ async function registerReserveWithBank(
AbsoluteTime.now(),
);
const oldTxState = computeWithdrawalTransactionStatus(r);
- r.status = WithdrawalGroupStatus.WaitConfirmBank;
+ r.status = WithdrawalGroupStatus.PendingWaitConfirmBank;
const newTxState = computeWithdrawalTransactionStatus(r);
await tx.withdrawalGroups.put(r);
return {
@@ -1928,8 +1938,8 @@ async function processReserveBankStatus(
withdrawalGroupId,
});
switch (withdrawalGroup?.status) {
- case WithdrawalGroupStatus.WaitConfirmBank:
- case WithdrawalGroupStatus.RegisteringBank:
+ case WithdrawalGroupStatus.PendingWaitConfirmBank:
+ case WithdrawalGroupStatus.PendingRegisteringBank:
break;
default:
return {
@@ -1969,8 +1979,8 @@ async function processReserveBankStatus(
return;
}
switch (r.status) {
- case WithdrawalGroupStatus.RegisteringBank:
- case WithdrawalGroupStatus.WaitConfirmBank:
+ case WithdrawalGroupStatus.PendingRegisteringBank:
+ case WithdrawalGroupStatus.PendingWaitConfirmBank:
break;
default:
return;
@@ -1981,7 +1991,7 @@ async function processReserveBankStatus(
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
const oldTxState = computeWithdrawalTransactionStatus(r);
r.wgInfo.bankInfo.timestampBankConfirmed = now;
- r.status = WithdrawalGroupStatus.BankAborted;
+ r.status = WithdrawalGroupStatus.FailedBankAborted;
const newTxState = computeWithdrawalTransactionStatus(r);
await tx.withdrawalGroups.put(r);
return {
@@ -2002,7 +2012,7 @@ async function processReserveBankStatus(
}
// FIXME: Why do we do this?!
- if (withdrawalGroup.status === WithdrawalGroupStatus.RegisteringBank) {
+ if (withdrawalGroup.status === WithdrawalGroupStatus.PendingRegisteringBank) {
await registerReserveWithBank(ws, withdrawalGroupId);
return await processReserveBankStatus(ws, withdrawalGroupId);
}
@@ -2016,8 +2026,8 @@ async function processReserveBankStatus(
}
// Re-check reserve status within transaction
switch (r.status) {
- case WithdrawalGroupStatus.RegisteringBank:
- case WithdrawalGroupStatus.WaitConfirmBank:
+ case WithdrawalGroupStatus.PendingRegisteringBank:
+ case WithdrawalGroupStatus.PendingWaitConfirmBank:
break;
default:
return undefined;
@@ -2030,7 +2040,7 @@ async function processReserveBankStatus(
logger.info("withdrawal: transfer confirmed by bank.");
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
r.wgInfo.bankInfo.timestampBankConfirmed = now;
- r.status = WithdrawalGroupStatus.QueryingStatus;
+ r.status = WithdrawalGroupStatus.PendingQueryingStatus;
// FIXME: Notification is deprecated with DD37.
ws.notify({
type: NotificationType.WithdrawalGroupBankConfirmed,
@@ -2276,7 +2286,7 @@ export async function acceptWithdrawalFromUri(
},
restrictAge: req.restrictAge,
forcedDenomSel: req.forcedDenomSel,
- reserveStatus: WithdrawalGroupStatus.RegisteringBank,
+ reserveStatus: WithdrawalGroupStatus.PendingRegisteringBank,
});
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
@@ -2291,19 +2301,14 @@ export async function acceptWithdrawalFromUri(
const processedWithdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, {
withdrawalGroupId,
});
- if (processedWithdrawalGroup?.status === WithdrawalGroupStatus.BankAborted) {
+ if (processedWithdrawalGroup?.status === WithdrawalGroupStatus.FailedBankAborted) {
throw TalerError.fromDetail(
TalerErrorCode.WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK,
{},
);
}
- // Start withdrawal in the background
- processWithdrawalGroup(ws, withdrawalGroupId, {
- forceNow: true,
- }).catch((err) => {
- logger.error("Processing withdrawal (after creation) failed:", err);
- });
+ ws.workAvailable.trigger();
return {
reservePub: withdrawalGroup.reservePub,
@@ -2337,7 +2342,7 @@ export async function createManualWithdrawal(
exchangeBaseUrl: req.exchangeBaseUrl,
forcedDenomSel: req.forcedDenomSel,
restrictAge: req.restrictAge,
- reserveStatus: WithdrawalGroupStatus.QueryingStatus,
+ reserveStatus: WithdrawalGroupStatus.PendingQueryingStatus,
});
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
@@ -2357,18 +2362,7 @@ export async function createManualWithdrawal(
return await getFundingPaytoUris(tx, withdrawalGroup.withdrawalGroupId);
});
- // Start withdrawal in the background (do not await!)
- // FIXME: We could also interrupt the task look if it is waiting and
- // rely on retry handling to re-process the withdrawal group.
- runOperationWithErrorReporting(
- ws,
- TaskIdentifiers.forWithdrawal(withdrawalGroup),
- async () => {
- return await processWithdrawalGroup(ws, withdrawalGroupId, {
- forceNow: true,
- });
- },
- );
+ ws.workAvailable.trigger();
return {
reservePub: withdrawalGroup.reservePub,
diff --git a/packages/taler-wallet-core/src/pending-types.ts b/packages/taler-wallet-core/src/pending-types.ts
index 0e83ef38c..23f9ae21f 100644
--- a/packages/taler-wallet-core/src/pending-types.ts
+++ b/packages/taler-wallet-core/src/pending-types.ts
@@ -37,9 +37,8 @@ export enum PendingTaskType {
Withdraw = "withdraw",
Deposit = "deposit",
Backup = "backup",
- // FIXME: Rename to peer-push-debit and peer-pull-debit
- PeerPushInitiation = "peer-push-initiation",
- PeerPullInitiation = "peer-pull-initiation",
+ PeerPushDebit = "peer-push-debit",
+ PeerPullCredit = "peer-pull-credit",
PeerPushCredit = "peer-push-credit",
PeerPullDebit = "peer-pull-debit",
}
@@ -83,7 +82,7 @@ export interface PendingExchangeUpdateTask {
* The wallet wants to send a peer push payment.
*/
export interface PendingPeerPushInitiationTask {
- type: PendingTaskType.PeerPushInitiation;
+ type: PendingTaskType.PeerPushDebit;
pursePub: string;
}
@@ -91,7 +90,7 @@ export interface PendingPeerPushInitiationTask {
* The wallet wants to send a peer pull payment.
*/
export interface PendingPeerPullInitiationTask {
- type: PendingTaskType.PeerPullInitiation;
+ type: PendingTaskType.PeerPullCredit;
pursePub: string;
}
diff --git a/packages/taler-wallet-core/src/util/retries.ts b/packages/taler-wallet-core/src/util/retries.ts
index a021087be..12e1df7e9 100644
--- a/packages/taler-wallet-core/src/util/retries.ts
+++ b/packages/taler-wallet-core/src/util/retries.ts
@@ -197,9 +197,9 @@ export type ParsedTaskIdentifier =
| { tag: PendingTaskType.ExchangeCheckRefresh; exchangeBaseUrl: string }
| { tag: PendingTaskType.ExchangeUpdate; exchangeBaseUrl: string }
| { tag: PendingTaskType.PeerPullDebit; peerPullPaymentIncomingId: string }
- | { tag: PendingTaskType.PeerPullInitiation; pursePub: string }
+ | { tag: PendingTaskType.PeerPullCredit; pursePub: string }
| { tag: PendingTaskType.PeerPushCredit; peerPushPaymentIncomingId: string }
- | { tag: PendingTaskType.PeerPushInitiation; pursePub: string }
+ | { tag: PendingTaskType.PeerPushDebit; pursePub: string }
| { tag: PendingTaskType.Purchase; proposalId: string }
| { tag: PendingTaskType.Recoup; recoupGroupId: string }
| { tag: PendingTaskType.TipPickup; walletTipId: string }
@@ -223,9 +223,9 @@ export function constructTaskIdentifier(p: ParsedTaskIdentifier): string {
return `${p.tag}:${p.peerPullPaymentIncomingId}`;
case PendingTaskType.PeerPushCredit:
return `${p.tag}:${p.peerPushPaymentIncomingId}`;
- case PendingTaskType.PeerPullInitiation:
+ case PendingTaskType.PeerPullCredit:
return `${p.tag}:${p.pursePub}`;
- case PendingTaskType.PeerPushInitiation:
+ case PendingTaskType.PeerPushDebit:
return `${p.tag}:${p.pursePub}`;
case PendingTaskType.Purchase:
return `${p.tag}:${p.proposalId}`;
@@ -276,12 +276,12 @@ export namespace TaskIdentifiers {
export function forPeerPushPaymentInitiation(
ppi: PeerPushPaymentInitiationRecord,
): string {
- return `${PendingTaskType.PeerPushInitiation}:${ppi.pursePub}`;
+ return `${PendingTaskType.PeerPushDebit}:${ppi.pursePub}`;
}
export function forPeerPullPaymentInitiation(
ppi: PeerPullPaymentInitiationRecord,
): string {
- return `${PendingTaskType.PeerPullInitiation}:${ppi.pursePub}`;
+ return `${PendingTaskType.PeerPullCredit}:${ppi.pursePub}`;
}
export function forPeerPullPaymentDebit(
ppi: PeerPullPaymentIncomingRecord,
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index 733c239f9..ed174e33b 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -208,7 +208,7 @@ import {
processPeerPullCredit,
processPeerPullDebit,
processPeerPushCredit,
- processPeerPushInitiation,
+ processPeerPushDebit,
} from "./operations/pay-peer.js";
import { getPendingOperations } from "./operations/pending.js";
import {
@@ -314,9 +314,9 @@ async function callOperationHandler(
}
case PendingTaskType.Backup:
return await processBackupForProvider(ws, pending.backupProviderBaseUrl);
- case PendingTaskType.PeerPushInitiation:
- return await processPeerPushInitiation(ws, pending.pursePub);
- case PendingTaskType.PeerPullInitiation:
+ case PendingTaskType.PeerPushDebit:
+ return await processPeerPushDebit(ws, pending.pursePub);
+ case PendingTaskType.PeerPullCredit:
return await processPeerPullCredit(ws, pending.pursePub);
case PendingTaskType.PeerPullDebit:
return await processPeerPullDebit(ws, pending.peerPullPaymentIncomingId);
@@ -439,7 +439,7 @@ async function runTaskLoop(
});
// Wait until either the timeout, or we are notified (via the latch)
// that more work might be available.
- await Promise.race([timeout, ws.latch.wait()]);
+ await Promise.race([timeout, ws.workAvailable.wait()]);
} else {
logger.trace(
`running ${pending.pendingOperations.length} pending operations`,
@@ -1659,7 +1659,7 @@ class InternalWalletStateImpl implements InternalWalletState {
merchantInfoCache: Record<string, MerchantInfo> = {};
readonly timerGroup: TimerGroup;
- latch = new AsyncCondition();
+ workAvailable = new AsyncCondition();
stopped = false;
listeners: NotificationListener[] = [];