From 1edc144b3595ae1ab6b8af7a43d26b811b2c2623 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 23 Apr 2024 03:09:40 +0200 Subject: wallet-core: pass options object to all transactions --- packages/taler-wallet-core/src/pay-merchant.ts | 508 ++++++++++++++----------- 1 file changed, 285 insertions(+), 223 deletions(-) (limited to 'packages/taler-wallet-core/src/pay-merchant.ts') diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts index f9d20d415..49ebc282e 100644 --- a/packages/taler-wallet-core/src/pay-merchant.ts +++ b/packages/taler-wallet-core/src/pay-merchant.ts @@ -200,7 +200,7 @@ export class PayMerchantTransactionContext implements TransactionContext { const ws = this.wex; const extraStores = opts.extraStores ?? []; const transitionInfo = await ws.db.runReadWriteTx( - ["purchases", ...extraStores], + { storeNames: ["purchases", ...extraStores] }, async (tx) => { const purchaseRec = await tx.purchases.get(this.proposalId); if (!purchaseRec) { @@ -227,26 +227,29 @@ export class PayMerchantTransactionContext implements TransactionContext { async deleteTransaction(): Promise { const { wex: ws, proposalId } = this; - await ws.db.runReadWriteTx(["purchases", "tombstones"], async (tx) => { - let found = false; - const purchase = await tx.purchases.get(proposalId); - if (purchase) { - found = true; - await tx.purchases.delete(proposalId); - } - if (found) { - await tx.tombstones.put({ - id: TombstoneTag.DeletePayment + ":" + proposalId, - }); - } - }); + await ws.db.runReadWriteTx( + { storeNames: ["purchases", "tombstones"] }, + async (tx) => { + let found = false; + const purchase = await tx.purchases.get(proposalId); + if (purchase) { + found = true; + await tx.purchases.delete(proposalId); + } + if (found) { + await tx.tombstones.put({ + id: TombstoneTag.DeletePayment + ":" + proposalId, + }); + } + }, + ); } async suspendTransaction(): Promise { const { wex, proposalId, transactionId } = this; wex.taskScheduler.stopShepherdTask(this.taskId); const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const purchase = await tx.purchases.get(proposalId); if (!purchase) { @@ -268,15 +271,17 @@ export class PayMerchantTransactionContext implements TransactionContext { async abortTransaction(): Promise { const { wex, proposalId, transactionId } = this; const transitionInfo = await wex.db.runReadWriteTx( - [ - "purchases", - "refreshGroups", - "refreshSessions", - "denominations", - "coinAvailability", - "coins", - "operationRetries", - ], + { + storeNames: [ + "purchases", + "refreshGroups", + "refreshSessions", + "denominations", + "coinAvailability", + "coins", + "operationRetries", + ], + }, async (tx) => { const purchase = await tx.purchases.get(proposalId); if (!purchase) { @@ -344,7 +349,7 @@ export class PayMerchantTransactionContext implements TransactionContext { async resumeTransaction(): Promise { const { wex, proposalId, transactionId, taskId: retryTag } = this; const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const purchase = await tx.purchases.get(proposalId); if (!purchase) { @@ -367,14 +372,16 @@ export class PayMerchantTransactionContext implements TransactionContext { async failTransaction(): Promise { const { wex, proposalId, transactionId } = this; const transitionInfo = await wex.db.runReadWriteTx( - [ - "purchases", - "refreshGroups", - "denominations", - "coinAvailability", - "coins", - "operationRetries", - ], + { + storeNames: [ + "purchases", + "refreshGroups", + "denominations", + "coinAvailability", + "coins", + "operationRetries", + ], + }, async (tx) => { const purchase = await tx.purchases.get(proposalId); if (!purchase) { @@ -415,15 +422,18 @@ export class RefundTransactionContext implements TransactionContext { async deleteTransaction(): Promise { const { wex, refundGroupId, transactionId } = this; - await wex.db.runReadWriteTx(["refundGroups", "tombstones"], async (tx) => { - const refundRecord = await tx.refundGroups.get(refundGroupId); - if (!refundRecord) { - return; - } - await tx.refundGroups.delete(refundGroupId); - await tx.tombstones.put({ id: transactionId }); - // FIXME: Also tombstone the refund items, so that they won't reappear. - }); + await wex.db.runReadWriteTx( + { storeNames: ["refundGroups", "tombstones"] }, + async (tx) => { + const refundRecord = await tx.refundGroups.get(refundGroupId); + if (!refundRecord) { + return; + } + await tx.refundGroups.delete(refundGroupId); + await tx.tombstones.put({ id: transactionId }); + // FIXME: Also tombstone the refund items, so that they won't reappear. + }, + ); } suspendTransaction(): Promise { @@ -455,31 +465,34 @@ export async function getTotalPaymentCost( currency: string, pcs: SelectedProspectiveCoin[], ): Promise { - return wex.db.runReadOnlyTx(["coins", "denominations"], async (tx) => { - const costs: AmountJson[] = []; - for (let i = 0; i < pcs.length; i++) { - const denom = await tx.denominations.get([ - pcs[i].exchangeBaseUrl, - pcs[i].denomPubHash, - ]); - if (!denom) { - throw Error( - "can't calculate payment cost, denomination for coin not found", + return wex.db.runReadOnlyTx( + { storeNames: ["coins", "denominations"] }, + async (tx) => { + const costs: AmountJson[] = []; + for (let i = 0; i < pcs.length; i++) { + const denom = await tx.denominations.get([ + pcs[i].exchangeBaseUrl, + pcs[i].denomPubHash, + ]); + if (!denom) { + throw Error( + "can't calculate payment cost, denomination for coin not found", + ); + } + const amountLeft = Amounts.sub(denom.value, pcs[i].contribution).amount; + const refreshCost = await getTotalRefreshCost( + wex, + tx, + DenominationRecord.toDenomInfo(denom), + amountLeft, ); + costs.push(Amounts.parseOrThrow(pcs[i].contribution)); + costs.push(refreshCost); } - const amountLeft = Amounts.sub(denom.value, pcs[i].contribution).amount; - const refreshCost = await getTotalRefreshCost( - wex, - tx, - DenominationRecord.toDenomInfo(denom), - amountLeft, - ); - costs.push(Amounts.parseOrThrow(pcs[i].contribution)); - costs.push(refreshCost); - } - const zero = Amounts.zeroOfCurrency(currency); - return Amounts.sum([zero, ...costs]).amount; - }); + const zero = Amounts.zeroOfCurrency(currency); + return Amounts.sum([zero, ...costs]).amount; + }, + ); } async function failProposalPermanently( @@ -492,7 +505,7 @@ async function failProposalPermanently( proposalId, }); const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const p = await tx.purchases.get(proposalId); if (!p) { @@ -554,7 +567,10 @@ export async function expectProposalDownload( if (parentTx) { return getFromTransaction(parentTx); } - return await wex.db.runReadOnlyTx(["contractTerms"], getFromTransaction); + return await wex.db.runReadOnlyTx( + { storeNames: ["contractTerms"] }, + getFromTransaction, + ); } export function extractContractData( @@ -593,9 +609,12 @@ async function processDownloadProposal( wex: WalletExecutionContext, proposalId: string, ): Promise { - const proposal = await wex.db.runReadOnlyTx(["purchases"], async (tx) => { - return await tx.purchases.get(proposalId); - }); + const proposal = await wex.db.runReadOnlyTx( + { storeNames: ["purchases"] }, + async (tx) => { + return await tx.purchases.get(proposalId); + }, + ); if (!proposal) { return TaskRunResult.finished(); @@ -766,7 +785,7 @@ async function processDownloadProposal( logger.trace(`extracted contract data: ${j2s(contractData)}`); const transitionInfo = await wex.db.runReadWriteTx( - ["purchases", "contractTerms"], + { storeNames: ["purchases", "contractTerms"] }, async (tx) => { const p = await tx.purchases.get(proposalId); if (!p) { @@ -839,12 +858,15 @@ async function createOrReusePurchase( claimToken: string | undefined, noncePriv: string | undefined, ): Promise { - const oldProposals = await wex.db.runReadOnlyTx(["purchases"], async (tx) => { - return tx.purchases.indexes.byUrlAndOrderId.getAll([ - merchantBaseUrl, - orderId, - ]); - }); + const oldProposals = await wex.db.runReadOnlyTx( + { storeNames: ["purchases"] }, + async (tx) => { + return tx.purchases.indexes.byUrlAndOrderId.getAll([ + merchantBaseUrl, + orderId, + ]); + }, + ); const oldProposal = oldProposals.find((p) => { return ( @@ -878,7 +900,7 @@ async function createOrReusePurchase( // if this transaction was shared and the order is paid then it // means that another wallet already paid the proposal const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const p = await tx.purchases.get(oldProposal.proposalId); if (!p) { @@ -944,7 +966,7 @@ async function createOrReusePurchase( }; const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { await tx.purchases.put(proposalRecord); const oldTxState: TransactionState = { @@ -978,7 +1000,7 @@ async function storeFirstPaySuccess( }); const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now()); const transitionInfo = await wex.db.runReadWriteTx( - ["contractTerms", "purchases"], + { storeNames: ["contractTerms", "purchases"] }, async (tx) => { const purchase = await tx.purchases.get(proposalId); @@ -1042,7 +1064,7 @@ async function storePayReplaySuccess( proposalId, }); const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const purchase = await tx.purchases.get(proposalId); @@ -1085,9 +1107,12 @@ async function handleInsufficientFunds( ): Promise { logger.trace("handling insufficient funds, trying to re-select coins"); - const proposal = await wex.db.runReadOnlyTx(["purchases"], async (tx) => { - return tx.purchases.get(proposalId); - }); + const proposal = await wex.db.runReadOnlyTx( + { storeNames: ["purchases"] }, + async (tx) => { + return tx.purchases.get(proposalId); + }, + ); if (!proposal) { return; } @@ -1127,16 +1152,19 @@ async function handleInsufficientFunds( return; } - await wex.db.runReadOnlyTx(["coins", "denominations"], async (tx) => { - for (let i = 0; i < payCoinSelection.coinPubs.length; i++) { - const coinPub = payCoinSelection.coinPubs[i]; - const contrib = payCoinSelection.coinContributions[i]; - prevPayCoins.push({ - coinPub, - contribution: Amounts.parseOrThrow(contrib), - }); - } - }); + await wex.db.runReadOnlyTx( + { storeNames: ["coins", "denominations"] }, + async (tx) => { + for (let i = 0; i < payCoinSelection.coinPubs.length; i++) { + const coinPub = payCoinSelection.coinPubs[i]; + const contrib = payCoinSelection.coinContributions[i]; + prevPayCoins.push({ + coinPub, + contribution: Amounts.parseOrThrow(contrib), + }); + } + }, + ); const res = await selectPayCoins(wex, { restrictExchanges: { @@ -1165,14 +1193,16 @@ async function handleInsufficientFunds( logger.trace("re-selected coins"); await wex.db.runReadWriteTx( - [ - "purchases", - "coins", - "coinAvailability", - "denominations", - "refreshGroups", - "refreshSessions", - ], + { + storeNames: [ + "purchases", + "coins", + "coinAvailability", + "denominations", + "refreshGroups", + "refreshSessions", + ], + }, async (tx) => { const p = await tx.purchases.get(proposalId); if (!p) { @@ -1221,9 +1251,12 @@ async function checkPaymentByProposalId( proposalId: string, sessionId?: string, ): Promise { - let proposal = await wex.db.runReadOnlyTx(["purchases"], async (tx) => { - return tx.purchases.get(proposalId); - }); + let proposal = await wex.db.runReadOnlyTx( + { storeNames: ["purchases"] }, + async (tx) => { + return tx.purchases.get(proposalId); + }, + ); if (!proposal) { throw Error(`could not get proposal ${proposalId}`); } @@ -1232,7 +1265,7 @@ async function checkPaymentByProposalId( if (existingProposalId) { logger.trace("using existing purchase for same product"); const oldProposal = await wex.db.runReadOnlyTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { return tx.purchases.get(existingProposalId); }, @@ -1266,9 +1299,12 @@ async function checkPaymentByProposalId( }); // First check if we already paid for it. - const purchase = await wex.db.runReadOnlyTx(["purchases"], async (tx) => { - return tx.purchases.get(proposalId); - }); + const purchase = await wex.db.runReadOnlyTx( + { storeNames: ["purchases"] }, + async (tx) => { + return tx.purchases.get(proposalId); + }, + ); if ( !purchase || @@ -1344,7 +1380,7 @@ async function checkPaymentByProposalId( ); logger.trace(`last: ${purchase.lastSessionId}, current: ${sessionId}`); const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const p = await tx.purchases.get(proposalId); if (!p) { @@ -1421,9 +1457,12 @@ export async function getContractTermsDetails( wex: WalletExecutionContext, proposalId: string, ): Promise { - const proposal = await wex.db.runReadOnlyTx(["purchases"], async (tx) => { - return tx.purchases.get(proposalId); - }); + const proposal = await wex.db.runReadOnlyTx( + { storeNames: ["purchases"] }, + async (tx) => { + return tx.purchases.get(proposalId); + }, + ); if (!proposal) { throw Error(`proposal with id ${proposalId} not found`); @@ -1513,7 +1552,7 @@ async function internalWaitProposalDownloaded( ): Promise { while (true) { const { purchase, retryInfo } = await ctx.wex.db.runReadOnlyTx( - ["purchases", "operationRetries"], + { storeNames: ["purchases", "operationRetries"] }, async (tx) => { return { purchase: await tx.purchases.get(ctx.proposalId), @@ -1610,24 +1649,27 @@ export async function generateDepositPermissions( coin: CoinRecord; denom: DenominationRecord; }> = []; - await wex.db.runReadOnlyTx(["coins", "denominations"], async (tx) => { - for (let i = 0; i < payCoinSel.coinContributions.length; i++) { - const coin = await tx.coins.get(payCoinSel.coinPubs[i]); - if (!coin) { - throw Error("can't pay, allocated coin not found anymore"); - } - const denom = await tx.denominations.get([ - coin.exchangeBaseUrl, - coin.denomPubHash, - ]); - if (!denom) { - throw Error( - "can't pay, denomination of allocated coin not found anymore", - ); + await wex.db.runReadOnlyTx( + { storeNames: ["coins", "denominations"] }, + async (tx) => { + for (let i = 0; i < payCoinSel.coinContributions.length; i++) { + const coin = await tx.coins.get(payCoinSel.coinPubs[i]); + if (!coin) { + throw Error("can't pay, allocated coin not found anymore"); + } + const denom = await tx.denominations.get([ + coin.exchangeBaseUrl, + coin.denomPubHash, + ]); + if (!denom) { + throw Error( + "can't pay, denomination of allocated coin not found anymore", + ); + } + coinWithDenom.push({ coin, denom }); } - coinWithDenom.push({ coin, denom }); - } - }); + }, + ); for (let i = 0; i < payCoinSel.coinContributions.length; i++) { const { coin, denom } = coinWithDenom[i]; @@ -1662,7 +1704,7 @@ async function internalWaitPaymentResult( ): Promise { while (true) { const txRes = await ctx.wex.db.runReadOnlyTx( - ["purchases", "operationRetries"], + { storeNames: ["purchases", "operationRetries"] }, async (tx) => { const purchase = await tx.purchases.get(ctx.proposalId); const retryRecord = await tx.operationRetries.get(ctx.taskId); @@ -1776,9 +1818,12 @@ export async function confirmPay( logger.trace( `executing confirmPay with proposalId ${proposalId} and sessionIdOverride ${sessionIdOverride}`, ); - const proposal = await wex.db.runReadOnlyTx(["purchases"], async (tx) => { - return tx.purchases.get(proposalId); - }); + const proposal = await wex.db.runReadOnlyTx( + { storeNames: ["purchases"] }, + async (tx) => { + return tx.purchases.get(proposalId); + }, + ); if (!proposal) { throw Error(`proposal with id ${proposalId} not found`); @@ -1790,7 +1835,7 @@ export async function confirmPay( } const existingPurchase = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const purchase = await tx.purchases.get(proposalId); if ( @@ -1875,14 +1920,16 @@ export async function confirmPay( ); const transitionInfo = await wex.db.runReadWriteTx( - [ - "purchases", - "coins", - "refreshGroups", - "refreshSessions", - "denominations", - "coinAvailability", - ], + { + storeNames: [ + "purchases", + "coins", + "refreshGroups", + "refreshSessions", + "denominations", + "coinAvailability", + ], + }, async (tx) => { const p = await tx.purchases.get(proposal.proposalId); if (!p) { @@ -1954,9 +2001,12 @@ export async function processPurchase( wex: WalletExecutionContext, proposalId: string, ): Promise { - const purchase = await wex.db.runReadOnlyTx(["purchases"], async (tx) => { - return tx.purchases.get(proposalId); - }); + const purchase = await wex.db.runReadOnlyTx( + { storeNames: ["purchases"] }, + async (tx) => { + return tx.purchases.get(proposalId); + }, + ); if (!purchase) { return { type: TaskRunResultType.Error, @@ -2013,9 +2063,12 @@ async function processPurchasePay( wex: WalletExecutionContext, proposalId: string, ): Promise { - const purchase = await wex.db.runReadOnlyTx(["purchases"], async (tx) => { - return tx.purchases.get(proposalId); - }); + const purchase = await wex.db.runReadOnlyTx( + { storeNames: ["purchases"] }, + async (tx) => { + return tx.purchases.get(proposalId); + }, + ); if (!purchase) { return { type: TaskRunResultType.Error, @@ -2056,7 +2109,7 @@ async function processPurchasePay( if (paid) { const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const p = await tx.purchases.get(purchase.proposalId); if (!p) { @@ -2128,14 +2181,16 @@ async function processPurchasePay( ); const transitionDone = await wex.db.runReadWriteTx( - [ - "purchases", - "coins", - "refreshGroups", - "refreshSessions", - "denominations", - "coinAvailability", - ], + { + storeNames: [ + "purchases", + "coins", + "refreshGroups", + "refreshSessions", + "denominations", + "coinAvailability", + ], + }, async (tx) => { const p = await tx.purchases.get(proposalId); if (!p) { @@ -2329,7 +2384,7 @@ export async function refuseProposal( proposalId, }); const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const proposal = await tx.purchases.get(proposalId); if (!proposal) { @@ -2603,42 +2658,45 @@ export async function sharePayment( merchantBaseUrl: string, orderId: string, ): Promise { - const result = await wex.db.runReadWriteTx(["purchases"], async (tx) => { - const p = await tx.purchases.indexes.byUrlAndOrderId.get([ - merchantBaseUrl, - orderId, - ]); - if (!p) { - logger.warn("purchase does not exist anymore"); - return undefined; - } - if ( - p.purchaseStatus !== PurchaseStatus.DialogProposed && - p.purchaseStatus !== PurchaseStatus.DialogShared - ) { - // FIXME: purchase can be shared before being paid - return undefined; - } - const oldTxState = computePayMerchantTransactionState(p); - if (p.purchaseStatus === PurchaseStatus.DialogProposed) { - p.purchaseStatus = PurchaseStatus.DialogShared; - p.shared = true; - await tx.purchases.put(p); - } + const result = await wex.db.runReadWriteTx( + { storeNames: ["purchases"] }, + async (tx) => { + const p = await tx.purchases.indexes.byUrlAndOrderId.get([ + merchantBaseUrl, + orderId, + ]); + if (!p) { + logger.warn("purchase does not exist anymore"); + return undefined; + } + if ( + p.purchaseStatus !== PurchaseStatus.DialogProposed && + p.purchaseStatus !== PurchaseStatus.DialogShared + ) { + // FIXME: purchase can be shared before being paid + return undefined; + } + const oldTxState = computePayMerchantTransactionState(p); + if (p.purchaseStatus === PurchaseStatus.DialogProposed) { + p.purchaseStatus = PurchaseStatus.DialogShared; + p.shared = true; + await tx.purchases.put(p); + } - const newTxState = computePayMerchantTransactionState(p); + const newTxState = computePayMerchantTransactionState(p); - return { - proposalId: p.proposalId, - nonce: p.noncePriv, - session: p.lastSessionId ?? p.downloadSessionId, - token: p.claimToken, - transitionInfo: { - oldTxState, - newTxState, - }, - }; - }); + return { + proposalId: p.proposalId, + nonce: p.noncePriv, + session: p.lastSessionId ?? p.downloadSessionId, + token: p.claimToken, + transitionInfo: { + oldTxState, + newTxState, + }, + }; + }, + ); if (result === undefined) { throw Error("This purchase can't be shared"); @@ -2713,7 +2771,7 @@ async function processPurchaseDialogShared( ); if (paid) { const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const p = await tx.purchases.get(purchase.proposalId); if (!p) { @@ -2752,15 +2810,16 @@ async function processPurchaseAutoRefund( const download = await expectProposalDownload(wex, purchase); - const noAutoRefundOrExpired = !purchase.autoRefundDeadline || - AbsoluteTime.isExpired( - AbsoluteTime.fromProtocolTimestamp( - timestampProtocolFromDb(purchase.autoRefundDeadline), - ), - ) + const noAutoRefundOrExpired = + !purchase.autoRefundDeadline || + AbsoluteTime.isExpired( + AbsoluteTime.fromProtocolTimestamp( + timestampProtocolFromDb(purchase.autoRefundDeadline), + ), + ); const totalKnownRefund = await wex.db.runReadOnlyTx( - ["refundGroups"], + { storeNames: ["refundGroups"] }, async (tx) => { const refunds = await tx.refundGroups.indexes.byProposalId.getAll( purchase.proposalId, @@ -2778,12 +2837,13 @@ async function processPurchaseAutoRefund( }, ); - const refundedIsLessThanPrice = Amounts.cmp(download.contractData.amount, totalKnownRefund) === +1 - const nothingMoreToRefund = !refundedIsLessThanPrice + const refundedIsLessThanPrice = + Amounts.cmp(download.contractData.amount, totalKnownRefund) === +1; + const nothingMoreToRefund = !refundedIsLessThanPrice; if (noAutoRefundOrExpired || nothingMoreToRefund) { const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const p = await tx.purchases.get(purchase.proposalId); if (!p) { @@ -2831,7 +2891,7 @@ async function processPurchaseAutoRefund( if (orderStatus.refund_pending) { const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const p = await tx.purchases.get(purchase.proposalId); if (!p) { @@ -2875,7 +2935,7 @@ async function processPurchaseAbortingRefund( throw Error("can't abort, no coins selected"); } - await wex.db.runReadOnlyTx(["coins"], async (tx) => { + await wex.db.runReadOnlyTx({ storeNames: ["coins"] }, async (tx) => { for (let i = 0; i < payCoinSelection.coinPubs.length; i++) { const coinPub = payCoinSelection.coinPubs[i]; const coin = await tx.coins.get(coinPub); @@ -2981,7 +3041,7 @@ async function processPurchaseQueryRefund( if (!orderStatus.refund_pending) { const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const p = await tx.purchases.get(purchase.proposalId); if (!p) { @@ -3008,7 +3068,7 @@ async function processPurchaseQueryRefund( ).amount; const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const p = await tx.purchases.get(purchase.proposalId); if (!p) { @@ -3076,7 +3136,7 @@ export async function startRefundQueryForUri( throw Error("expected taler://refund URI"); } const purchaseRecord = await wex.db.runReadOnlyTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { return tx.purchases.indexes.byUrlAndOrderId.get([ parsedUri.merchantBaseUrl, @@ -3107,7 +3167,7 @@ export async function startQueryRefund( ): Promise { const ctx = new PayMerchantTransactionContext(wex, proposalId); const transitionInfo = await wex.db.runReadWriteTx( - ["purchases"], + { storeNames: ["purchases"] }, async (tx) => { const p = await tx.purchases.get(proposalId); if (!p) { @@ -3200,18 +3260,20 @@ async function storeRefunds( const currency = Amounts.currencyOf(download.contractData.amount); const result = await wex.db.runReadWriteTx( - [ - "coins", - "denominations", - "purchases", - "refundItems", - "refundGroups", - "denominations", - "coins", - "coinAvailability", - "refreshGroups", - "refreshSessions", - ], + { + storeNames: [ + "coins", + "denominations", + "purchases", + "refundItems", + "refundGroups", + "denominations", + "coins", + "coinAvailability", + "refreshGroups", + "refreshSessions", + ], + }, async (tx) => { const myPurchase = await tx.purchases.get(purchase.proposalId); if (!myPurchase) { -- cgit v1.2.3