summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts')
-rw-r--r--packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts123
1 files changed, 57 insertions, 66 deletions
diff --git a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts
index 427961f44..23976f11b 100644
--- a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts
+++ b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts
@@ -17,6 +17,7 @@
import {
AcceptPeerPushPaymentResponse,
Amounts,
+ CancellationToken,
ConfirmPeerPushCreditRequest,
ContractTermsUtil,
ExchangePurseMergeRequest,
@@ -54,9 +55,10 @@ import {
InternalWalletState,
KycPendingInfo,
KycUserType,
- PeerPushPaymentIncomingRecord,
PeerPushCreditStatus,
+ PeerPushPaymentIncomingRecord,
PendingTaskType,
+ TaskId,
WithdrawalGroupStatus,
WithdrawalRecordType,
timestampPreciseToDb,
@@ -69,9 +71,8 @@ import {
TombstoneTag,
TransactionContext,
constructTaskIdentifier,
- runLongpollAsync,
} from "./common.js";
-import { fetchFreshExchange, markExchangeUsed } from "./exchanges.js";
+import { fetchFreshExchange } from "./exchanges.js";
import {
codecForExchangePurseStatus,
getMergeReserveInfo,
@@ -81,7 +82,6 @@ import {
constructTransactionIdentifier,
notifyTransition,
parseTransactionIdentifier,
- stopLongpolling,
} from "./transactions.js";
import {
PerformCreateWithdrawalGroupResult,
@@ -93,8 +93,8 @@ import {
const logger = new Logger("pay-peer-push-credit.ts");
export class PeerPushCreditTransactionContext implements TransactionContext {
- private transactionId: string;
- private retryTag: string;
+ readonly transactionId: string;
+ readonly retryTag: TaskId;
constructor(
public ws: InternalWalletState,
@@ -141,7 +141,6 @@ export class PeerPushCreditTransactionContext implements TransactionContext {
async suspendTransaction(): Promise<void> {
const { ws, peerPushCreditId, retryTag, transactionId } = this;
- stopLongpolling(ws, retryTag);
const transitionInfo = await ws.db.runReadWriteTx(
["peerPushCredit"],
async (tx) => {
@@ -191,11 +190,11 @@ export class PeerPushCreditTransactionContext implements TransactionContext {
},
);
notifyTransition(ws, transactionId, transitionInfo);
+ ws.taskScheduler.stopShepherdTask(retryTag);
}
async abortTransaction(): Promise<void> {
const { ws, peerPushCreditId, retryTag, transactionId } = this;
- stopLongpolling(ws, retryTag);
const transitionInfo = await ws.db.runReadWriteTx(
["peerPushCredit"],
async (tx) => {
@@ -248,11 +247,11 @@ export class PeerPushCreditTransactionContext implements TransactionContext {
},
);
notifyTransition(ws, transactionId, transitionInfo);
+ ws.taskScheduler.startShepherdTask(retryTag);
}
async resumeTransaction(): Promise<void> {
const { ws, peerPushCreditId, retryTag, transactionId } = this;
- stopLongpolling(ws, retryTag);
const transitionInfo = await ws.db.runReadWriteTx(
["peerPushCredit"],
async (tx) => {
@@ -300,13 +299,12 @@ export class PeerPushCreditTransactionContext implements TransactionContext {
return undefined;
},
);
- ws.workAvailable.trigger();
notifyTransition(ws, transactionId, transitionInfo);
+ ws.taskScheduler.startShepherdTask(retryTag);
}
async failTransaction(): Promise<void> {
const { ws, peerPushCreditId, retryTag, transactionId } = this;
- stopLongpolling(ws, retryTag);
const transitionInfo = await ws.db.runReadWriteTx(
["peerPushCredit"],
async (tx) => {
@@ -349,8 +347,9 @@ export class PeerPushCreditTransactionContext implements TransactionContext {
return undefined;
},
);
- ws.workAvailable.trigger();
+ ws.taskScheduler.stopShepherdTask(retryTag);
notifyTransition(ws, transactionId, transitionInfo);
+ ws.taskScheduler.startShepherdTask(retryTag);
}
}
@@ -521,63 +520,51 @@ async function longpollKycStatus(
exchangeUrl: string,
kycInfo: KycPendingInfo,
userType: KycUserType,
+ cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const transactionId = constructTransactionIdentifier({
tag: TransactionType.PeerPushCredit,
peerPushCreditId,
});
- const retryTag = constructTaskIdentifier({
- tag: PendingTaskType.PeerPushCredit,
- peerPushCreditId,
- });
-
- runLongpollAsync(ws, retryTag, async (ct) => {
- const url = new URL(
- `kyc-check/${kycInfo.requirementRow}/${kycInfo.paytoHash}/${userType}`,
- exchangeUrl,
- );
- url.searchParams.set("timeout_ms", "10000");
- logger.info(`kyc url ${url.href}`);
- const kycStatusRes = await ws.http.fetch(url.href, {
- method: "GET",
- cancellationToken: ct,
- });
- if (
- kycStatusRes.status === HttpStatusCode.Ok ||
- //FIXME: NoContent is not expected https://docs.taler.net/core/api-exchange.html#post--purses-$PURSE_PUB-merge
- // remove after the exchange is fixed or clarified
- kycStatusRes.status === HttpStatusCode.NoContent
- ) {
- const transitionInfo = await ws.db
- .mktx((x) => [x.peerPushCredit])
- .runReadWrite(async (tx) => {
- const peerInc = await tx.peerPushCredit.get(peerPushCreditId);
- if (!peerInc) {
- return;
- }
- if (peerInc.status !== PeerPushCreditStatus.PendingMergeKycRequired) {
- return;
- }
- const oldTxState = computePeerPushCreditTransactionState(peerInc);
- peerInc.status = PeerPushCreditStatus.PendingMerge;
- const newTxState = computePeerPushCreditTransactionState(peerInc);
- await tx.peerPushCredit.put(peerInc);
- return { oldTxState, newTxState };
- });
- notifyTransition(ws, transactionId, transitionInfo);
- return { ready: true };
- } else if (kycStatusRes.status === HttpStatusCode.Accepted) {
- // FIXME: Do we have to update the URL here?
- return { ready: false };
- } else {
- throw Error(
- `unexpected response from kyc-check (${kycStatusRes.status})`,
- );
- }
+ const url = new URL(
+ `kyc-check/${kycInfo.requirementRow}/${kycInfo.paytoHash}/${userType}`,
+ exchangeUrl,
+ );
+ url.searchParams.set("timeout_ms", "10000");
+ logger.info(`kyc url ${url.href}`);
+ const kycStatusRes = await ws.http.fetch(url.href, {
+ method: "GET",
+ cancellationToken,
});
- return {
- type: TaskRunResultType.Longpoll,
- };
+ if (
+ kycStatusRes.status === HttpStatusCode.Ok ||
+ //FIXME: NoContent is not expected https://docs.taler.net/core/api-exchange.html#post--purses-$PURSE_PUB-merge
+ // remove after the exchange is fixed or clarified
+ kycStatusRes.status === HttpStatusCode.NoContent
+ ) {
+ const transitionInfo = await ws.db
+ .mktx((x) => [x.peerPushCredit])
+ .runReadWrite(async (tx) => {
+ const peerInc = await tx.peerPushCredit.get(peerPushCreditId);
+ if (!peerInc) {
+ return;
+ }
+ if (peerInc.status !== PeerPushCreditStatus.PendingMergeKycRequired) {
+ return;
+ }
+ const oldTxState = computePeerPushCreditTransactionState(peerInc);
+ peerInc.status = PeerPushCreditStatus.PendingMerge;
+ const newTxState = computePeerPushCreditTransactionState(peerInc);
+ await tx.peerPushCredit.put(peerInc);
+ return { oldTxState, newTxState };
+ });
+ notifyTransition(ws, transactionId, transitionInfo);
+ } else if (kycStatusRes.status === HttpStatusCode.Accepted) {
+ // FIXME: Do we have to update the URL here?
+ } else {
+ throw Error(`unexpected response from kyc-check (${kycStatusRes.status})`);
+ }
+ return TaskRunResult.backoff();
}
async function processPeerPushCreditKycRequired(
@@ -786,7 +773,7 @@ async function handlePendingMerge(
);
notifyTransition(ws, transactionId, txRes?.peerPushCreditTransition);
- return TaskRunResult.finished();
+ return TaskRunResult.backoff();
}
async function handlePendingWithdrawing(
@@ -839,13 +826,14 @@ async function handlePendingWithdrawing(
return TaskRunResult.finished();
} else {
// FIXME: Return indicator that we depend on the other operation!
- return TaskRunResult.pending();
+ return TaskRunResult.backoff();
}
}
export async function processPeerPushCredit(
ws: InternalWalletState,
peerPushCreditId: string,
+ cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
let peerInc: PeerPushPaymentIncomingRecord | undefined;
let contractTerms: PeerContractTerms | undefined;
@@ -886,6 +874,7 @@ export async function processPeerPushCredit(
peerInc.exchangeBaseUrl,
peerInc.kycInfo,
"individual",
+ cancellationToken,
);
}
@@ -940,7 +929,9 @@ export async function confirmPeerPushCredit(
);
}
- ws.workAvailable.trigger();
+ const ctx = new PeerPushCreditTransactionContext(ws, peerPushCreditId);
+
+ ws.taskScheduler.startShepherdTask(ctx.retryTag);
const transactionId = constructTransactionIdentifier({
tag: TransactionType.PeerPushCredit,