summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/pay-merchant.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/pay-merchant.ts')
-rw-r--r--packages/taler-wallet-core/src/pay-merchant.ts428
1 files changed, 200 insertions, 228 deletions
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts
index 73dc59ba2..a576930ba 100644
--- a/packages/taler-wallet-core/src/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/pay-merchant.ts
@@ -33,7 +33,6 @@ import {
AmountString,
assertUnreachable,
AsyncFlag,
- CancellationToken,
checkDbInvariant,
codecForAbortResponse,
codecForMerchantContractTerms,
@@ -142,6 +141,7 @@ import {
EXCHANGE_COINS_LOCK,
getDenomInfo,
InternalWalletState,
+ WalletExecutionContext,
} from "./wallet.js";
import { getCandidateWithdrawalDenomsTx } from "./withdraw.js";
@@ -155,7 +155,7 @@ export class PayMerchantTransactionContext implements TransactionContext {
readonly taskId: TaskIdStr;
constructor(
- public ws: InternalWalletState,
+ public wex: WalletExecutionContext,
public proposalId: string,
) {
this.transactionId = constructTransactionIdentifier({
@@ -198,7 +198,7 @@ export class PayMerchantTransactionContext implements TransactionContext {
>,
) => Promise<TransitionResult>,
): Promise<void> {
- const ws = this.ws;
+ const ws = this.wex;
const extraStores = opts.extraStores ?? [];
const transitionInfo = await ws.db.runReadWriteTx(
["purchases", ...extraStores],
@@ -227,7 +227,7 @@ export class PayMerchantTransactionContext implements TransactionContext {
}
async deleteTransaction(): Promise<void> {
- const { ws, proposalId } = this;
+ const { wex: ws, proposalId } = this;
await ws.db.runReadWriteTx(["purchases", "tombstones"], async (tx) => {
let found = false;
const purchase = await tx.purchases.get(proposalId);
@@ -244,7 +244,7 @@ export class PayMerchantTransactionContext implements TransactionContext {
}
async suspendTransaction(): Promise<void> {
- const { ws, proposalId, transactionId } = this;
+ const { wex: ws, proposalId, transactionId } = this;
ws.taskScheduler.stopShepherdTask(this.taskId);
const transitionInfo = await ws.db.runReadWriteTx(
["purchases"],
@@ -267,8 +267,8 @@ export class PayMerchantTransactionContext implements TransactionContext {
}
async abortTransaction(): Promise<void> {
- const { ws, proposalId, transactionId } = this;
- const transitionInfo = await ws.db.runReadWriteTx(
+ const { wex, proposalId, transactionId } = this;
+ const transitionInfo = await wex.db.runReadWriteTx(
[
"purchases",
"refreshGroups",
@@ -308,7 +308,7 @@ export class PayMerchantTransactionContext implements TransactionContext {
});
}
await createRefreshGroup(
- ws,
+ wex,
tx,
currency,
refreshCoins,
@@ -328,13 +328,13 @@ export class PayMerchantTransactionContext implements TransactionContext {
return { oldTxState, newTxState };
},
);
- ws.taskScheduler.stopShepherdTask(this.taskId);
- notifyTransition(ws, transactionId, transitionInfo);
- ws.taskScheduler.startShepherdTask(this.taskId);
+ wex.taskScheduler.stopShepherdTask(this.taskId);
+ notifyTransition(wex, transactionId, transitionInfo);
+ wex.taskScheduler.startShepherdTask(this.taskId);
}
async resumeTransaction(): Promise<void> {
- const { ws, proposalId, transactionId, taskId: retryTag } = this;
+ const { wex: ws, proposalId, transactionId, taskId: retryTag } = this;
const transitionInfo = await ws.db.runReadWriteTx(
["purchases"],
async (tx) => {
@@ -357,7 +357,7 @@ export class PayMerchantTransactionContext implements TransactionContext {
}
async failTransaction(): Promise<void> {
- const { ws, proposalId, transactionId } = this;
+ const { wex: ws, proposalId, transactionId } = this;
const transitionInfo = await ws.db.runReadWriteTx(
[
"purchases",
@@ -396,7 +396,7 @@ export class RefundTransactionContext implements TransactionContext {
public transactionId: TransactionIdStr;
public taskId: TaskIdStr | undefined = undefined;
constructor(
- public ws: InternalWalletState,
+ public wex: WalletExecutionContext,
public refundGroupId: string,
) {
this.transactionId = constructTransactionIdentifier({
@@ -406,8 +406,8 @@ export class RefundTransactionContext implements TransactionContext {
}
async deleteTransaction(): Promise<void> {
- const { ws, refundGroupId, transactionId } = this;
- await ws.db.runReadWriteTx(["refundGroups", "tombstones"], async (tx) => {
+ const { wex, refundGroupId, transactionId } = this;
+ await wex.db.runReadWriteTx(["refundGroups", "tombstones"], async (tx) => {
const refundRecord = await tx.refundGroups.get(refundGroupId);
if (!refundRecord) {
return;
@@ -443,11 +443,11 @@ export class RefundTransactionContext implements TransactionContext {
* of coins that are too small to spend.
*/
export async function getTotalPaymentCost(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
pcs: PayCoinSelection,
): Promise<AmountJson> {
const currency = Amounts.currencyOf(pcs.paymentAmount);
- return ws.db.runReadOnlyTx(["coins", "denominations"], async (tx) => {
+ return wex.db.runReadOnlyTx(["coins", "denominations"], async (tx) => {
const costs: AmountJson[] = [];
for (let i = 0; i < pcs.coinPubs.length; i++) {
const coin = await tx.coins.get(pcs.coinPubs[i]);
@@ -464,7 +464,7 @@ export async function getTotalPaymentCost(
);
}
const allDenoms = await getCandidateWithdrawalDenomsTx(
- ws,
+ wex,
tx,
coin.exchangeBaseUrl,
currency,
@@ -477,7 +477,7 @@ export async function getTotalPaymentCost(
allDenoms,
DenominationRecord.toDenomInfo(denom),
amountLeft,
- ws.config.testing.denomselAllowLate,
+ wex.ws.config.testing.denomselAllowLate,
);
costs.push(Amounts.parseOrThrow(pcs.coinContributions[i]));
costs.push(refreshCost);
@@ -488,7 +488,7 @@ export async function getTotalPaymentCost(
}
async function failProposalPermanently(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
err: TalerErrorDetail,
): Promise<void> {
@@ -496,7 +496,7 @@ async function failProposalPermanently(
tag: TransactionType.Payment,
proposalId,
});
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const p = await tx.purchases.get(proposalId);
@@ -511,7 +511,7 @@ async function failProposalPermanently(
return { oldTxState, newTxState };
},
);
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
}
function getPayRequestTimeout(purchase: PurchaseRecord): Duration {
@@ -525,7 +525,7 @@ function getPayRequestTimeout(purchase: PurchaseRecord): Duration {
* Return the proposal download data for a purchase, throw if not available.
*/
export async function expectProposalDownload(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
p: PurchaseRecord,
parentTx?: WalletDbReadOnlyTransaction<["contractTerms"]>,
): Promise<{
@@ -559,7 +559,7 @@ export async function expectProposalDownload(
if (parentTx) {
return getFromTransaction(parentTx);
}
- return await ws.db.runReadOnlyTx(["contractTerms"], getFromTransaction);
+ return await wex.db.runReadOnlyTx(["contractTerms"], getFromTransaction);
}
export function extractContractData(
@@ -603,11 +603,10 @@ export function extractContractData(
}
async function processDownloadProposal(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
- cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
- const proposal = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
+ const proposal = await wex.db.runReadOnlyTx(["purchases"], async (tx) => {
return await tx.purchases.get(proposalId);
});
@@ -615,7 +614,7 @@ async function processDownloadProposal(
return TaskRunResult.finished();
}
- const ctx = new PayMerchantTransactionContext(ws, proposalId);
+ const ctx = new PayMerchantTransactionContext(wex, proposalId);
if (proposal.purchaseStatus != PurchaseStatus.PendingDownloadingProposal) {
logger.error(
@@ -644,10 +643,10 @@ async function processDownloadProposal(
requestBody.token = proposal.claimToken;
}
- const httpResponse = await ws.http.fetch(orderClaimUrl, {
+ const httpResponse = await wex.http.fetch(orderClaimUrl, {
method: "POST",
body: requestBody,
- cancellationToken,
+ cancellationToken: wex.cancellationToken,
});
const r = await readSuccessResponseJsonOrErrorCode(
httpResponse,
@@ -692,7 +691,7 @@ async function processDownloadProposal(
{},
"validation for well-formedness failed",
);
- await failProposalPermanently(ws, proposalId, err);
+ await failProposalPermanently(wex, proposalId, err);
throw makePendingOperationFailedError(
err,
TransactionType.Payment,
@@ -718,7 +717,7 @@ async function processDownloadProposal(
{},
`schema validation failed: ${e}`,
);
- await failProposalPermanently(ws, proposalId, err);
+ await failProposalPermanently(wex, proposalId, err);
throw makePendingOperationFailedError(
err,
TransactionType.Payment,
@@ -726,7 +725,7 @@ async function processDownloadProposal(
);
}
- const sigValid = await ws.cryptoApi.isValidContractTermsSignature({
+ const sigValid = await wex.cryptoApi.isValidContractTermsSignature({
contractTermsHash,
merchantPub: parsedContractTerms.merchant_pub,
sig: proposalResp.sig,
@@ -741,7 +740,7 @@ async function processDownloadProposal(
},
"merchant's signature on contract terms is invalid",
);
- await failProposalPermanently(ws, proposalId, err);
+ await failProposalPermanently(wex, proposalId, err);
throw makePendingOperationFailedError(
err,
TransactionType.Payment,
@@ -763,7 +762,7 @@ async function processDownloadProposal(
},
"merchant base URL mismatch",
);
- await failProposalPermanently(ws, proposalId, err);
+ await failProposalPermanently(wex, proposalId, err);
throw makePendingOperationFailedError(
err,
TransactionType.Payment,
@@ -779,7 +778,7 @@ async function processDownloadProposal(
logger.trace(`extracted contract data: ${j2s(contractData)}`);
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases", "contractTerms"],
async (tx) => {
const p = await tx.purchases.get(proposalId);
@@ -835,7 +834,7 @@ async function processDownloadProposal(
},
);
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
return TaskRunResult.progress();
}
@@ -846,15 +845,14 @@ async function processDownloadProposal(
* return the old proposal ID.
*/
async function createOrReusePurchase(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
merchantBaseUrl: string,
orderId: string,
sessionId: string | undefined,
claimToken: string | undefined,
noncePriv: string | undefined,
- cancellationToken: CancellationToken,
): Promise<string> {
- const oldProposals = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
+ const oldProposals = await wex.db.runReadOnlyTx(["purchases"], async (tx) => {
return tx.purchases.indexes.byUrlAndOrderId.getAll([
merchantBaseUrl,
orderId,
@@ -882,17 +880,13 @@ async function createOrReusePurchase(
}) for order ${orderId} at ${merchantBaseUrl}`,
);
if (oldProposal.purchaseStatus === PurchaseStatus.DialogShared) {
- const download = await expectProposalDownload(ws, oldProposal);
- const paid = await checkIfOrderIsAlreadyPaid(
- ws,
- download.contractData,
- cancellationToken,
- );
+ const download = await expectProposalDownload(wex, oldProposal);
+ const paid = await checkIfOrderIsAlreadyPaid(wex, download.contractData);
logger.info(`old proposal paid: ${paid}`);
if (paid) {
// if this transaction was shared and the order is paid then it
// means that another wallet already paid the proposal
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const p = await tx.purchases.get(oldProposal.proposalId);
@@ -912,7 +906,7 @@ async function createOrReusePurchase(
tag: TransactionType.Payment,
proposalId: oldProposal.proposalId,
});
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
}
}
return oldProposal.proposalId;
@@ -924,10 +918,10 @@ async function createOrReusePurchase(
shared = true;
noncePair = {
priv: noncePriv,
- pub: (await ws.cryptoApi.eddsaGetPublic({ priv: noncePriv })).pub,
+ pub: (await wex.cryptoApi.eddsaGetPublic({ priv: noncePriv })).pub,
};
} else {
- noncePair = await ws.cryptoApi.createEddsaKeypair({});
+ noncePair = await wex.cryptoApi.createEddsaKeypair({});
}
const { priv, pub } = noncePair;
@@ -958,7 +952,7 @@ async function createOrReusePurchase(
shared: shared,
};
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
await tx.purchases.put(proposalRecord);
@@ -977,12 +971,12 @@ async function createOrReusePurchase(
tag: TransactionType.Payment,
proposalId,
});
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
return proposalId;
}
async function storeFirstPaySuccess(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
sessionId: string | undefined,
payResponse: MerchantPayResponse,
@@ -992,7 +986,7 @@ async function storeFirstPaySuccess(
proposalId,
});
const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now());
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["contractTerms", "purchases"],
async (tx) => {
const purchase = await tx.purchases.get(proposalId);
@@ -1044,11 +1038,11 @@ async function storeFirstPaySuccess(
};
},
);
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
}
async function storePayReplaySuccess(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
sessionId: string | undefined,
): Promise<void> {
@@ -1056,7 +1050,7 @@ async function storePayReplaySuccess(
tag: TransactionType.Payment,
proposalId,
});
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const purchase = await tx.purchases.get(proposalId);
@@ -1082,7 +1076,7 @@ async function storePayReplaySuccess(
return { oldTxState, newTxState };
},
);
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
}
/**
@@ -1094,13 +1088,13 @@ async function storePayReplaySuccess(
* (3) re-do coin selection with the bad coin removed
*/
async function handleInsufficientFunds(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
err: TalerErrorDetail,
): Promise<void> {
logger.trace("handling insufficient funds, trying to re-select coins");
- const proposal = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
+ const proposal = await wex.db.runReadOnlyTx(["purchases"], async (tx) => {
return tx.purchases.get(proposalId);
});
if (!proposal) {
@@ -1128,7 +1122,7 @@ async function handleInsufficientFunds(
throw new TalerProtocolViolationError();
}
- const { contractData } = await expectProposalDownload(ws, proposal);
+ const { contractData } = await expectProposalDownload(wex, proposal);
const prevPayCoins: PreviousPayCoins = [];
@@ -1139,7 +1133,7 @@ async function handleInsufficientFunds(
const payCoinSelection = payInfo.payCoinSelection;
- await ws.db.runReadOnlyTx(["coins", "denominations"], async (tx) => {
+ await wex.db.runReadOnlyTx(["coins", "denominations"], async (tx) => {
for (let i = 0; i < payCoinSelection.coinPubs.length; i++) {
const coinPub = payCoinSelection.coinPubs[i];
if (coinPub === brokenCoinPub) {
@@ -1166,7 +1160,7 @@ async function handleInsufficientFunds(
}
});
- const res = await selectPayCoinsNew(ws, {
+ const res = await selectPayCoinsNew(wex, {
auditors: [],
exchanges: contractData.allowedExchanges,
wireMethod: contractData.wireMethod,
@@ -1185,7 +1179,7 @@ async function handleInsufficientFunds(
logger.trace("re-selected coins");
- await ws.db.runReadWriteTx(
+ await wex.db.runReadWriteTx(
[
"purchases",
"coins",
@@ -1205,7 +1199,7 @@ async function handleInsufficientFunds(
payInfo.payCoinSelection = res.coinSel;
payInfo.payCoinSelectionUid = encodeCrock(getRandomBytes(32));
await tx.purchases.put(p);
- await spendCoins(ws, tx, {
+ await spendCoins(wex, tx, {
// allocationId: `txn:proposal:${p.proposalId}`,
allocationId: constructTransactionIdentifier({
tag: TransactionType.Payment,
@@ -1220,7 +1214,7 @@ async function handleInsufficientFunds(
},
);
- ws.notify({
+ wex.ws.notify({
type: NotificationType.BalanceChange,
hintTransactionId: constructTransactionIdentifier({
tag: TransactionType.Payment,
@@ -1233,11 +1227,11 @@ async function handleInsufficientFunds(
// FIXME: Does way more than checking the payment
// FIXME: Should return immediately.
async function checkPaymentByProposalId(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
sessionId?: string,
): Promise<PreparePayResult> {
- let proposal = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
+ let proposal = await wex.db.runReadOnlyTx(["purchases"], async (tx) => {
return tx.purchases.get(proposalId);
});
if (!proposal) {
@@ -1247,7 +1241,7 @@ async function checkPaymentByProposalId(
const existingProposalId = proposal.repurchaseProposalId;
if (existingProposalId) {
logger.trace("using existing purchase for same product");
- const oldProposal = await ws.db.runReadOnlyTx(
+ const oldProposal = await wex.db.runReadOnlyTx(
["purchases"],
async (tx) => {
return tx.purchases.get(existingProposalId);
@@ -1258,7 +1252,7 @@ async function checkPaymentByProposalId(
}
}
}
- const d = await expectProposalDownload(ws, proposal);
+ const d = await expectProposalDownload(wex, proposal);
const contractData = d.contractData;
const merchantSig = d.contractData.merchantSig;
if (!merchantSig) {
@@ -1267,7 +1261,7 @@ async function checkPaymentByProposalId(
proposalId = proposal.proposalId;
- const ctx = new PayMerchantTransactionContext(ws, proposalId);
+ const ctx = new PayMerchantTransactionContext(wex, proposalId);
const transactionId = ctx.transactionId;
@@ -1280,7 +1274,7 @@ async function checkPaymentByProposalId(
});
// First check if we already paid for it.
- const purchase = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
+ const purchase = await wex.db.runReadOnlyTx(["purchases"], async (tx) => {
return tx.purchases.get(proposalId);
});
@@ -1290,7 +1284,7 @@ async function checkPaymentByProposalId(
purchase.purchaseStatus === PurchaseStatus.DialogShared
) {
// If not already paid, check if we could pay for it.
- const res = await selectPayCoinsNew(ws, {
+ const res = await selectPayCoinsNew(wex, {
auditors: [],
exchanges: contractData.allowedExchanges,
contractTermsAmount: Amounts.parseOrThrow(contractData.amount),
@@ -1318,7 +1312,7 @@ async function checkPaymentByProposalId(
};
}
- const totalCost = await getTotalPaymentCost(ws, res.coinSel);
+ const totalCost = await getTotalPaymentCost(wex, res.coinSel);
logger.trace("costInfo", totalCost);
logger.trace("coinsForPayment", res);
@@ -1342,7 +1336,7 @@ async function checkPaymentByProposalId(
"automatically re-submitting payment with different session ID",
);
logger.trace(`last: ${purchase.lastSessionId}, current: ${sessionId}`);
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const p = await tx.purchases.get(proposalId);
@@ -1357,14 +1351,14 @@ async function checkPaymentByProposalId(
return { oldTxState, newTxState };
},
);
- notifyTransition(ws, transactionId, transitionInfo);
- ws.taskScheduler.startShepherdTask(ctx.taskId);
+ notifyTransition(wex, transactionId, transitionInfo);
+ wex.taskScheduler.startShepherdTask(ctx.taskId);
// FIXME: Consider changing the API here so that we don't have to
// wait inline for the repurchase.
- await waitPaymentResult(ws, proposalId, sessionId);
- const download = await expectProposalDownload(ws, purchase);
+ await waitPaymentResult(wex, proposalId, sessionId);
+ const download = await expectProposalDownload(wex, purchase);
return {
status: PreparePayResultType.AlreadyConfirmed,
contractTerms: download.contractTermsRaw,
@@ -1379,7 +1373,7 @@ async function checkPaymentByProposalId(
talerUri,
};
} else if (!purchase.timestampFirstSuccessfulPay) {
- const download = await expectProposalDownload(ws, purchase);
+ const download = await expectProposalDownload(wex, purchase);
return {
status: PreparePayResultType.AlreadyConfirmed,
contractTerms: download.contractTermsRaw,
@@ -1398,7 +1392,7 @@ async function checkPaymentByProposalId(
purchase.purchaseStatus === PurchaseStatus.Done ||
purchase.purchaseStatus === PurchaseStatus.PendingQueryingRefund ||
purchase.purchaseStatus === PurchaseStatus.PendingQueryingAutoRefund;
- const download = await expectProposalDownload(ws, purchase);
+ const download = await expectProposalDownload(wex, purchase);
return {
status: PreparePayResultType.AlreadyConfirmed,
contractTerms: download.contractTermsRaw,
@@ -1417,10 +1411,10 @@ async function checkPaymentByProposalId(
}
export async function getContractTermsDetails(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
): Promise<WalletContractData> {
- const proposal = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
+ const proposal = await wex.db.runReadOnlyTx(["purchases"], async (tx) => {
return tx.purchases.get(proposalId);
});
@@ -1428,7 +1422,7 @@ export async function getContractTermsDetails(
throw Error(`proposal with id ${proposalId} not found`);
}
- const d = await expectProposalDownload(ws, proposal);
+ const d = await expectProposalDownload(wex, proposal);
return d.contractData;
}
@@ -1440,7 +1434,7 @@ export async function getContractTermsDetails(
* yet send to the merchant.
*/
export async function preparePayForUri(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
talerPayUri: string,
): Promise<PreparePayResult> {
const uriResult = parsePayUri(talerPayUri);
@@ -1456,39 +1450,38 @@ export async function preparePayForUri(
}
const proposalId = await createOrReusePurchase(
- ws,
+ wex,
uriResult.merchantBaseUrl,
uriResult.orderId,
uriResult.sessionId,
uriResult.claimToken,
uriResult.noncePriv,
- CancellationToken.CONTINUE,
);
- await waitProposalDownloaded(ws, proposalId);
+ await waitProposalDownloaded(wex, proposalId);
- return checkPaymentByProposalId(ws, proposalId, uriResult.sessionId);
+ return checkPaymentByProposalId(wex, proposalId, uriResult.sessionId);
}
/**
* Wait until a proposal is at least downloaded.
*/
async function waitProposalDownloaded(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
): Promise<void> {
- const ctx = new PayMerchantTransactionContext(ws, proposalId);
+ const ctx = new PayMerchantTransactionContext(wex, proposalId);
logger.info(`waiting for ${ctx.transactionId} to be downloaded`);
- ws.taskScheduler.startShepherdTask(ctx.taskId);
+ wex.taskScheduler.startShepherdTask(ctx.taskId);
// FIXME: We should use Symbol.dispose magic here for cleanup!
const payNotifFlag = new AsyncFlag();
// Raise exchangeNotifFlag whenever we get a notification
// about our exchange.
- const cancelNotif = ws.addNotificationListener((notif) => {
+ const cancelNotif = wex.ws.addNotificationListener((notif) => {
if (
notif.type === NotificationType.TransactionStateTransition &&
notif.transactionId === ctx.transactionId
@@ -1511,7 +1504,7 @@ async function internalWaitProposalDownloaded(
payNotifFlag: AsyncFlag,
): Promise<void> {
while (true) {
- const { purchase, retryInfo } = await ctx.ws.db.runReadOnlyTx(
+ const { purchase, retryInfo } = await ctx.wex.db.runReadOnlyTx(
["purchases", "operationRetries"],
async (tx) => {
return {
@@ -1539,7 +1532,7 @@ async function internalWaitProposalDownloaded(
}
export async function preparePayForTemplate(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
req: PreparePayTemplateRequest,
): Promise<PreparePayResult> {
const parsedUri = parsePayTemplateUri(req.talerPayTemplateUri);
@@ -1575,7 +1568,7 @@ export async function preparePayForTemplate(
`templates/${parsedUri.templateId}`,
parsedUri.merchantBaseUrl,
);
- const httpReq = await ws.http.fetch(reqUrl.href, {
+ const httpReq = await wex.http.fetch(reqUrl.href, {
method: "POST",
body: templateDetails,
});
@@ -1591,7 +1584,7 @@ export async function preparePayForTemplate(
claimToken: resp.token,
});
- return await preparePayForUri(ws, payUri);
+ return await preparePayForUri(wex, payUri);
}
/**
@@ -1600,7 +1593,7 @@ export async function preparePayForTemplate(
* Accesses the database and the crypto worker.
*/
export async function generateDepositPermissions(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
payCoinSel: PayCoinSelection,
contractData: WalletContractData,
): Promise<CoinDepositPermission[]> {
@@ -1609,7 +1602,7 @@ export async function generateDepositPermissions(
coin: CoinRecord;
denom: DenominationRecord;
}> = [];
- await ws.db.runReadOnlyTx(["coins", "denominations"], async (tx) => {
+ await wex.db.runReadOnlyTx(["coins", "denominations"], async (tx) => {
for (let i = 0; i < payCoinSel.coinPubs.length; i++) {
const coin = await tx.coins.get(payCoinSel.coinPubs[i]);
if (!coin) {
@@ -1637,7 +1630,7 @@ export async function generateDepositPermissions(
coin.ageCommitmentProof,
)}`,
);
- const dp = await ws.cryptoApi.signDepositPermission({
+ const dp = await wex.cryptoApi.signDepositPermission({
coinPriv: coin.coinPriv,
coinPub: coin.coinPub,
contractTermsHash: contractData.contractTermsHash,
@@ -1665,7 +1658,7 @@ async function internalWaitPaymentResult(
waitSessionId?: string,
): Promise<ConfirmPayResult> {
while (true) {
- const txRes = await ctx.ws.db.runReadOnlyTx(
+ const txRes = await ctx.wex.db.runReadOnlyTx(
["purchases", "operationRetries"],
async (tx) => {
const purchase = await tx.purchases.get(ctx.proposalId);
@@ -1684,7 +1677,7 @@ async function internalWaitPaymentResult(
`purchase is in state ${PurchaseStatus[purchase.purchaseStatus]}`,
);
- const d = await expectProposalDownload(ctx.ws, purchase);
+ const d = await expectProposalDownload(ctx.wex, purchase);
if (txRes.purchase.timestampFirstSuccessfulPay) {
if (
@@ -1726,20 +1719,20 @@ async function internalWaitPaymentResult(
* b) the attempt to pay failed (merchant unavailable, etc.)
*/
async function waitPaymentResult(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
waitSessionId?: string,
): Promise<ConfirmPayResult> {
- const ctx = new PayMerchantTransactionContext(ws, proposalId);
+ const ctx = new PayMerchantTransactionContext(wex, proposalId);
- ws.taskScheduler.ensureRunning();
- ws.taskScheduler.startShepherdTask(ctx.taskId);
+ wex.taskScheduler.ensureRunning();
+ wex.taskScheduler.startShepherdTask(ctx.taskId);
// FIXME: Clean up using the new JS "using" / Symbol.dispose syntax.
const purchaseNotifFlag = new AsyncFlag();
// Raise purchaseNotifFlag whenever we get a notification
// about our purchase.
- const cancelNotif = ws.addNotificationListener((notif) => {
+ const cancelNotif = wex.ws.addNotificationListener((notif) => {
if (
notif.type === NotificationType.TransactionStateTransition &&
notif.transactionId === ctx.transactionId
@@ -1768,7 +1761,7 @@ async function waitPaymentResult(
* Confirm payment for a proposal previously claimed by the wallet.
*/
export async function confirmPay(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
transactionId: string,
sessionIdOverride?: string,
forcedCoinSel?: ForcedCoinSel,
@@ -1781,7 +1774,7 @@ export async function confirmPay(
logger.trace(
`executing confirmPay with proposalId ${proposalId} and sessionIdOverride ${sessionIdOverride}`,
);
- const proposal = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
+ const proposal = await wex.db.runReadOnlyTx(["purchases"], async (tx) => {
return tx.purchases.get(proposalId);
});
@@ -1789,12 +1782,12 @@ export async function confirmPay(
throw Error(`proposal with id ${proposalId} not found`);
}
- const d = await expectProposalDownload(ws, proposal);
+ const d = await expectProposalDownload(wex, proposal);
if (!d) {
throw Error("proposal is in invalid state");
}
- const existingPurchase = await ws.db.runReadWriteTx(
+ const existingPurchase = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const purchase = await tx.purchases.get(proposalId);
@@ -1817,18 +1810,18 @@ export async function confirmPay(
if (existingPurchase && existingPurchase.payInfo) {
logger.trace("confirmPay: submitting payment for existing purchase");
const ctx = new PayMerchantTransactionContext(
- ws,
+ wex,
existingPurchase.proposalId,
);
- await ws.taskScheduler.resetTaskRetries(ctx.taskId);
- return waitPaymentResult(ws, proposalId);
+ await wex.taskScheduler.resetTaskRetries(ctx.taskId);
+ return waitPaymentResult(wex, proposalId);
}
logger.trace("confirmPay: purchase record does not exist yet");
const contractData = d.contractData;
- const selectCoinsResult = await selectPayCoinsNew(ws, {
+ const selectCoinsResult = await selectPayCoinsNew(wex, {
auditors: [],
exchanges: contractData.allowedExchanges,
wireMethod: contractData.wireMethod,
@@ -1852,7 +1845,7 @@ export async function confirmPay(
}
const coinSelection = selectCoinsResult.coinSel;
- const payCostInfo = await getTotalPaymentCost(ws, coinSelection);
+ const payCostInfo = await getTotalPaymentCost(wex, coinSelection);
let sessionId: string | undefined;
if (sessionIdOverride) {
@@ -1865,7 +1858,7 @@ export async function confirmPay(
`recording payment on ${proposal.orderId} with session ID ${sessionId}`,
);
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
[
"purchases",
"coins",
@@ -1891,7 +1884,7 @@ export async function confirmPay(
p.timestampAccept = timestampPreciseToDb(TalerPreciseTimestamp.now());
p.purchaseStatus = PurchaseStatus.PendingPaying;
await tx.purchases.put(p);
- await spendCoins(ws, tx, {
+ await spendCoins(wex, tx, {
//`txn:proposal:${p.proposalId}`
allocationId: constructTransactionIdentifier({
tag: TransactionType.Payment,
@@ -1914,22 +1907,21 @@ export async function confirmPay(
},
);
- notifyTransition(ws, transactionId, transitionInfo);
- ws.notify({
+ notifyTransition(wex, transactionId, transitionInfo);
+ wex.ws.notify({
type: NotificationType.BalanceChange,
hintTransactionId: transactionId,
});
// Wait until we have completed the first attempt to pay.
- return waitPaymentResult(ws, proposalId);
+ return waitPaymentResult(wex, proposalId);
}
export async function processPurchase(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
- cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
- const purchase = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
+ const purchase = await wex.db.runReadOnlyTx(["purchases"], async (tx) => {
return tx.purchases.get(proposalId);
});
if (!purchase) {
@@ -1947,20 +1939,20 @@ export async function processPurchase(
switch (purchase.purchaseStatus) {
case PurchaseStatus.PendingDownloadingProposal:
- return processDownloadProposal(ws, proposalId, cancellationToken);
+ return processDownloadProposal(wex, proposalId);
case PurchaseStatus.PendingPaying:
case PurchaseStatus.PendingPayingReplay:
- return processPurchasePay(ws, proposalId, cancellationToken);
+ return processPurchasePay(wex, proposalId);
case PurchaseStatus.PendingQueryingRefund:
- return processPurchaseQueryRefund(ws, purchase, cancellationToken);
+ return processPurchaseQueryRefund(wex, purchase);
case PurchaseStatus.PendingQueryingAutoRefund:
- return processPurchaseAutoRefund(ws, purchase, cancellationToken);
+ return processPurchaseAutoRefund(wex, purchase);
case PurchaseStatus.AbortingWithRefund:
- return processPurchaseAbortingRefund(ws, purchase, cancellationToken);
+ return processPurchaseAbortingRefund(wex, purchase);
case PurchaseStatus.PendingAcceptRefund:
- return processPurchaseAcceptRefund(ws, purchase, cancellationToken);
+ return processPurchaseAcceptRefund(wex, purchase);
case PurchaseStatus.DialogShared:
- return processPurchaseDialogShared(ws, purchase, cancellationToken);
+ return processPurchaseDialogShared(wex, purchase);
case PurchaseStatus.FailedClaim:
case PurchaseStatus.Done:
case PurchaseStatus.DoneRepurchaseDetected:
@@ -1984,11 +1976,10 @@ export async function processPurchase(
}
async function processPurchasePay(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
- cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
- const purchase = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
+ const purchase = await wex.db.runReadOnlyTx(["purchases"], async (tx) => {
return tx.purchases.get(proposalId);
});
if (!purchase) {
@@ -2018,17 +2009,13 @@ async function processPurchasePay(
const payInfo = purchase.payInfo;
checkDbInvariant(!!payInfo, "payInfo");
- const download = await expectProposalDownload(ws, purchase);
+ const download = await expectProposalDownload(wex, purchase);
if (purchase.shared) {
- const paid = await checkIfOrderIsAlreadyPaid(
- ws,
- download.contractData,
- cancellationToken,
- );
+ const paid = await checkIfOrderIsAlreadyPaid(wex, download.contractData);
if (paid) {
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const p = await tx.purchases.get(purchase.proposalId);
@@ -2048,7 +2035,7 @@ async function processPurchasePay(
proposalId,
});
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
return {
type: TaskRunResultType.Error,
@@ -2069,7 +2056,7 @@ async function processPurchasePay(
let depositPermissions: CoinDepositPermission[];
// FIXME: Cache!
depositPermissions = await generateDepositPermissions(
- ws,
+ wex,
payInfo.payCoinSelection,
download.contractData,
);
@@ -2084,12 +2071,12 @@ async function processPurchasePay(
JSON.stringify(reqBody, undefined, 2),
);
- const resp = await ws.runSequentialized([EXCHANGE_COINS_LOCK], () =>
- ws.http.fetch(payUrl, {
+ const resp = await wex.ws.runSequentialized([EXCHANGE_COINS_LOCK], () =>
+ wex.http.fetch(payUrl, {
method: "POST",
body: reqBody,
timeout: getPayRequestTimeout(purchase),
- cancellationToken,
+ cancellationToken: wex.cancellationToken,
}),
);
@@ -2115,7 +2102,7 @@ async function processPurchasePay(
TalerErrorCode.MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS
) {
// Do this in the background, as it might take some time
- handleInsufficientFunds(ws, proposalId, err).catch(async (e) => {
+ handleInsufficientFunds(wex, proposalId, err).catch(async (e) => {
logger.error("handling insufficient funds failed");
logger.error(`${e.toString()}`);
});
@@ -2140,7 +2127,7 @@ async function processPurchasePay(
logger.trace("got success from pay URL", merchantResp);
const merchantPub = download.contractData.merchantPub;
- const { valid } = await ws.cryptoApi.isValidPaymentSignature({
+ const { valid } = await wex.cryptoApi.isValidPaymentSignature({
contractHash: download.contractData.contractTermsHash,
merchantPub,
sig: merchantResp.sig,
@@ -2152,7 +2139,7 @@ async function processPurchasePay(
throw Error("merchant payment signature invalid");
}
- await storeFirstPaySuccess(ws, proposalId, sessionId, merchantResp);
+ await storeFirstPaySuccess(wex, proposalId, sessionId, merchantResp);
} else {
const payAgainUrl = new URL(
`orders/${download.contractData.orderId}/paid`,
@@ -2164,11 +2151,11 @@ async function processPurchasePay(
session_id: sessionId ?? "",
};
logger.trace(`/paid request body: ${j2s(reqBody)}`);
- const resp = await ws.runSequentialized([EXCHANGE_COINS_LOCK], () =>
- ws.http.fetch(payAgainUrl, {
+ const resp = await wex.ws.runSequentialized([EXCHANGE_COINS_LOCK], () =>
+ wex.http.fetch(payAgainUrl, {
method: "POST",
body: reqBody,
- cancellationToken,
+ cancellationToken: wex.cancellationToken,
}),
);
logger.trace(`/paid response status: ${resp.status}`);
@@ -2182,21 +2169,21 @@ async function processPurchasePay(
"/paid failed",
);
}
- await storePayReplaySuccess(ws, proposalId, sessionId);
+ await storePayReplaySuccess(wex, proposalId, sessionId);
}
return TaskRunResult.progress();
}
export async function refuseProposal(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
): Promise<void> {
const transactionId = constructTransactionIdentifier({
tag: TransactionType.Payment,
proposalId,
});
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const proposal = await tx.purchases.get(proposalId);
@@ -2218,7 +2205,7 @@ export async function refuseProposal(
},
);
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
}
const transitionSuspend: {
@@ -2456,11 +2443,11 @@ export function computePayMerchantTransactionActions(
}
export async function sharePayment(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
merchantBaseUrl: string,
orderId: string,
): Promise<SharePaymentResult> {
- const result = await ws.db.runReadWriteTx(["purchases"], async (tx) => {
+ const result = await wex.db.runReadWriteTx(["purchases"], async (tx) => {
const p = await tx.purchases.indexes.byUrlAndOrderId.get([
merchantBaseUrl,
orderId,
@@ -2503,9 +2490,8 @@ export async function sharePayment(
}
async function checkIfOrderIsAlreadyPaid(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
contract: WalletContractData,
- cancellationToken: CancellationToken,
) {
const requestUrl = new URL(
`orders/${contract.orderId}`,
@@ -2515,8 +2501,8 @@ async function checkIfOrderIsAlreadyPaid(
requestUrl.searchParams.set("timeout_ms", "1000");
- const resp = await ws.http.fetch(requestUrl.href, {
- cancellationToken,
+ const resp = await wex.http.fetch(requestUrl.href, {
+ cancellationToken: wex.cancellationToken,
});
if (
resp.status === HttpStatusCode.Ok ||
@@ -2532,25 +2518,20 @@ async function checkIfOrderIsAlreadyPaid(
}
async function processPurchaseDialogShared(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
purchase: PurchaseRecord,
- cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const proposalId = purchase.proposalId;
logger.trace(`processing dialog-shared for proposal ${proposalId}`);
- const download = await expectProposalDownload(ws, purchase);
+ const download = await expectProposalDownload(wex, purchase);
if (purchase.purchaseStatus !== PurchaseStatus.DialogShared) {
return TaskRunResult.finished();
}
- const paid = await checkIfOrderIsAlreadyPaid(
- ws,
- download.contractData,
- cancellationToken,
- );
+ const paid = await checkIfOrderIsAlreadyPaid(wex, download.contractData);
if (paid) {
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const p = await tx.purchases.get(purchase.proposalId);
@@ -2570,31 +2551,25 @@ async function processPurchaseDialogShared(
proposalId,
});
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
}
return TaskRunResult.backoff();
}
async function processPurchaseAutoRefund(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
purchase: PurchaseRecord,
- cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const proposalId = purchase.proposalId;
logger.trace(`processing auto-refund for proposal ${proposalId}`);
- const taskId = constructTaskIdentifier({
- tag: PendingTaskType.Purchase,
- proposalId,
- });
-
const transactionId = constructTransactionIdentifier({
tag: TransactionType.Payment,
proposalId,
});
- const download = await expectProposalDownload(ws, purchase);
+ const download = await expectProposalDownload(wex, purchase);
if (
!purchase.autoRefundDeadline ||
@@ -2604,7 +2579,7 @@ async function processPurchaseAutoRefund(
),
)
) {
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const p = await tx.purchases.get(purchase.proposalId);
@@ -2623,7 +2598,7 @@ async function processPurchaseAutoRefund(
return { oldTxState, newTxState };
},
);
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
return TaskRunResult.finished();
}
@@ -2639,8 +2614,8 @@ async function processPurchaseAutoRefund(
requestUrl.searchParams.set("timeout_ms", "1000");
requestUrl.searchParams.set("await_refund_obtained", "yes");
- const resp = await ws.http.fetch(requestUrl.href, {
- cancellationToken,
+ const resp = await wex.http.fetch(requestUrl.href, {
+ cancellationToken: wex.cancellationToken,
});
// FIXME: Check other status codes!
@@ -2651,7 +2626,7 @@ async function processPurchaseAutoRefund(
);
if (orderStatus.refund_pending) {
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const p = await tx.purchases.get(purchase.proposalId);
@@ -2669,19 +2644,18 @@ async function processPurchaseAutoRefund(
return { oldTxState, newTxState };
},
);
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
}
return TaskRunResult.backoff();
}
async function processPurchaseAbortingRefund(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
purchase: PurchaseRecord,
- cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const proposalId = purchase.proposalId;
- const download = await expectProposalDownload(ws, purchase);
+ const download = await expectProposalDownload(wex, purchase);
logger.trace(`processing aborting-refund for proposal ${proposalId}`);
const requestUrl = new URL(
@@ -2696,7 +2670,7 @@ async function processPurchaseAbortingRefund(
throw Error("can't abort, no coins selected");
}
- await ws.db.runReadOnlyTx(["coins"], async (tx) => {
+ await wex.db.runReadOnlyTx(["coins"], async (tx) => {
for (let i = 0; i < payCoinSelection.coinPubs.length; i++) {
const coinPub = payCoinSelection.coinPubs[i];
const coin = await tx.coins.get(coinPub);
@@ -2716,10 +2690,10 @@ async function processPurchaseAbortingRefund(
logger.trace(`making order abort request to ${requestUrl.href}`);
- const abortHttpResp = await ws.http.fetch(requestUrl.href, {
+ const abortHttpResp = await wex.http.fetch(requestUrl.href, {
method: "POST",
body: abortReq,
- cancellationToken,
+ cancellationToken: wex.cancellationToken,
});
if (abortHttpResp.status === HttpStatusCode.NotFound) {
@@ -2728,7 +2702,7 @@ async function processPurchaseAbortingRefund(
err.code ===
TalerErrorCode.MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_NOT_FOUND
) {
- const ctx = new PayMerchantTransactionContext(ws, proposalId);
+ const ctx = new PayMerchantTransactionContext(wex, proposalId);
await ctx.transition(async (rec) => {
if (rec.purchaseStatus === PurchaseStatus.AbortingWithRefund) {
rec.purchaseStatus = PurchaseStatus.AbortedOrderDeleted;
@@ -2766,18 +2740,17 @@ async function processPurchaseAbortingRefund(
),
});
}
- return await storeRefunds(ws, purchase, refunds, RefundReason.AbortRefund);
+ return await storeRefunds(wex, purchase, refunds, RefundReason.AbortRefund);
}
async function processPurchaseQueryRefund(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
purchase: PurchaseRecord,
- cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const proposalId = purchase.proposalId;
logger.trace(`processing query-refund for proposal ${proposalId}`);
- const download = await expectProposalDownload(ws, purchase);
+ const download = await expectProposalDownload(wex, purchase);
const requestUrl = new URL(
`orders/${download.contractData.orderId}`,
@@ -2788,8 +2761,8 @@ async function processPurchaseQueryRefund(
download.contractData.contractTermsHash,
);
- const resp = await ws.http.fetch(requestUrl.href, {
- cancellationToken,
+ const resp = await wex.http.fetch(requestUrl.href, {
+ cancellationToken: wex.cancellationToken,
});
const orderStatus = await readSuccessResponseJsonOrThrow(
resp,
@@ -2802,7 +2775,7 @@ async function processPurchaseQueryRefund(
});
if (!orderStatus.refund_pending) {
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const p = await tx.purchases.get(purchase.proposalId);
@@ -2821,7 +2794,7 @@ async function processPurchaseQueryRefund(
return { oldTxState, newTxState };
},
);
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
return TaskRunResult.progress();
} else {
const refundAwaiting = Amounts.sub(
@@ -2829,7 +2802,7 @@ async function processPurchaseQueryRefund(
Amounts.parseOrThrow(orderStatus.refund_taken),
).amount;
- const transitionInfo = await ws.db.runReadWriteTx(
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const p = await tx.purchases.get(purchase.proposalId);
@@ -2848,17 +2821,16 @@ async function processPurchaseQueryRefund(
return { oldTxState, newTxState };
},
);
- notifyTransition(ws, transactionId, transitionInfo);
+ notifyTransition(wex, transactionId, transitionInfo);
return TaskRunResult.progress();
}
}
async function processPurchaseAcceptRefund(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
purchase: PurchaseRecord,
- cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
- const download = await expectProposalDownload(ws, purchase);
+ const download = await expectProposalDownload(wex, purchase);
const requestUrl = new URL(
`orders/${download.contractData.orderId}/refund`,
@@ -2867,12 +2839,12 @@ async function processPurchaseAcceptRefund(
logger.trace(`making refund request to ${requestUrl.href}`);
- const request = await ws.http.fetch(requestUrl.href, {
+ const request = await wex.http.fetch(requestUrl.href, {
method: "POST",
body: {
h_contract: download.contractData.contractTermsHash,
},
- cancellationToken,
+ cancellationToken: wex.cancellationToken,
});
const refundResponse = await readSuccessResponseJsonOrThrow(
@@ -2880,7 +2852,7 @@ async function processPurchaseAcceptRefund(
codecForMerchantOrderRefundPickupResponse(),
);
return await storeRefunds(
- ws,
+ wex,
purchase,
refundResponse.refunds,
RefundReason.AbortRefund,
@@ -2888,7 +2860,7 @@ async function processPurchaseAcceptRefund(
}
export async function startRefundQueryForUri(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
talerUri: string,
): Promise<StartRefundQueryForUriResponse> {
const parsedUri = parseTalerUri(talerUri);
@@ -2898,7 +2870,7 @@ export async function startRefundQueryForUri(
if (parsedUri.type !== TalerUriAction.Refund) {
throw Error("expected taler://refund URI");
}
- const purchaseRecord = await ws.db.runReadOnlyTx(
+ const purchaseRecord = await wex.db.runReadOnlyTx(
["purchases"],
async (tx) => {
return tx.purchases.indexes.byUrlAndOrderId.get([
@@ -2918,18 +2890,18 @@ export async function startRefundQueryForUri(
tag: TransactionType.Payment,
proposalId,
});
- await startQueryRefund(ws, proposalId);
+ await startQueryRefund(wex, proposalId);
return {
transactionId,
};
}
export async function startQueryRefund(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
proposalId: string,
): Promise<void> {
- const ctx = new PayMerchantTransactionContext(ws, proposalId);
- const transitionInfo = await ws.db.runReadWriteTx(
+ const ctx = new PayMerchantTransactionContext(wex, proposalId);
+ const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
const p = await tx.purchases.get(proposalId);
@@ -2947,12 +2919,12 @@ export async function startQueryRefund(
return { oldTxState, newTxState };
},
);
- notifyTransition(ws, ctx.transactionId, transitionInfo);
- ws.taskScheduler.startShepherdTask(ctx.taskId);
+ notifyTransition(wex, ctx.transactionId, transitionInfo);
+ wex.taskScheduler.startShepherdTask(ctx.taskId);
}
async function computeRefreshRequest(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
tx: WalletDbReadWriteTransaction<["coins", "denominations"]>,
items: RefundItemRecord[],
): Promise<CoinRefreshRequest[]> {
@@ -2963,7 +2935,7 @@ async function computeRefreshRequest(
throw Error("coin not found");
}
const denomInfo = await getDenomInfo(
- ws,
+ wex,
tx,
coin.exchangeBaseUrl,
coin.denomPubHash,
@@ -3004,7 +2976,7 @@ function getItemStatus(rf: MerchantCoinRefundStatus): RefundItemStatus {
* Store refunds, possibly creating a new refund group.
*/
async function storeRefunds(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
purchase: PurchaseRecord,
refunds: MerchantCoinRefundStatus[],
reason: RefundReason,
@@ -3019,10 +2991,10 @@ async function storeRefunds(
const newRefundGroupId = encodeCrock(randomBytes(32));
const now = TalerPreciseTimestamp.now();
- const download = await expectProposalDownload(ws, purchase);
+ const download = await expectProposalDownload(wex, purchase);
const currency = Amounts.currencyOf(download.contractData.amount);
- const result = await ws.db.runReadWriteTx(
+ const result = await wex.db.runReadWriteTx(
[
"coins",
"denominations",
@@ -3116,12 +3088,12 @@ async function storeRefunds(
if (newGroup) {
const amountsRaw = newGroupRefunds.map((x) => x.refundAmount);
const refreshCoins = await computeRefreshRequest(
- ws,
+ wex,
tx,
newGroupRefunds,
);
const outInfo = await calculateRefreshOutput(
- ws,
+ wex,
tx,
currency,
refreshCoins,
@@ -3172,9 +3144,9 @@ async function storeRefunds(
refundGroup.status = RefundGroupStatus.Failed;
}
await tx.refundGroups.put(refundGroup);
- const refreshCoins = await computeRefreshRequest(ws, tx, items);
+ const refreshCoins = await computeRefreshRequest(wex, tx, items);
await createRefreshGroup(
- ws,
+ wex,
tx,
Amounts.currencyOf(download.contractData.amount),
refreshCoins,
@@ -3215,7 +3187,7 @@ async function storeRefunds(
return TaskRunResult.finished();
}
- notifyTransition(ws, transactionId, result.transitionInfo);
+ notifyTransition(wex, transactionId, result.transitionInfo);
if (result.numPendingItemsTotal > 0) {
return TaskRunResult.backoff();